Skip to content
Merged
Show file tree
Hide file tree
Changes from 9 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions CSS_template_literal.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<LanguageInjectionConfiguration>
<injection language="CSS" injector-id="js">
<display-name>CSS template literal</display-name>
<single-file value="true" />
<place><![CDATA[taggedString("css")]]></place>
<templateTag>css</templateTag>
</injection>
</LanguageInjectionConfiguration>
326 changes: 293 additions & 33 deletions package-lock.json

Large diffs are not rendered by default.

4 changes: 4 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -72,5 +72,9 @@
"homepage": "https://github.com/zakodium-oss/react-ocl#readme",
"volta": {
"node": "24.11.0"
},
"dependencies": {
"@emotion/is-prop-valid": "^1.4.0",
"@emotion/styled": "^11.14.1"
}
}
73 changes: 73 additions & 0 deletions src/components/svg/svg_editor.styled.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import isPropValid from '@emotion/is-prop-valid';
import styled from '@emotion/styled';

export const greekLetters = {
alpha: 'α',
beta: 'β',
gamma: 'γ',
delta: 'δ',
epsilon: 'ε',
zeta: 'ζ',
eta: 'η',
theta: 'θ',
} as const;
const greekLetterNames = Object.keys(greekLetters);
const greeksFirstLine = greekLetterNames.slice(0, 6);
const greeksLastLine = greekLetterNames.slice(6);

export const primes = {
prime1: '′',
prime2: '″',
prime3: '‴',
};
const primeNames = Object.keys(primes);

export const AtomLabelEditFormStyled = styled.form`
--box-size: 24px;

position: absolute;
z-index: 1;
line-height: 1;
font-size: 16px;
display: grid;
grid-template-columns: repeat(4, var(--box-size));
grid-template-rows: repeat(3, var(--box-size));
grid-template-areas:
'input input input input submit cancel'
'${greeksFirstLine.join(' ')}'
'${greeksLastLine.join(' ')} . ${primeNames.join(' ')}';
place-items: stretch;
gap: 0.25em;
border: 1px solid lightgray;
background-color: white;
padding: 0.25em;
box-sizing: border-box;
`;

export const AtomLabelEditInputStyled = styled.input`
grid-area: input;

padding: 0.25em;
border: solid 1px lightgrey;
border-radius: 3px;
font-family: sans-serif;
font-size: 13.3333px;

&:focus {
outline: auto;
}
`;

export const AtomLabelEditButtonStyled = styled('button', {
shouldForwardProp: (prop) => isPropValid(prop) && prop !== 'area',
})<{ area: string }>`
grid-area: ${(props) => props.area};

padding: 0.25em;
background-color: #efefef;
border: none;
border-radius: 5px;
font-family: sans-serif;
width: var(--box-size);
font-size: 13.3333px;
`;
83 changes: 27 additions & 56 deletions src/components/svg/svg_editor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,13 @@ import {
import type { State } from './editor/reducer.js';
import { stateReducer } from './editor/reducer.js';
import { useHighlight } from './editor/use_highlight.js';
import {
AtomLabelEditButtonStyled,
AtomLabelEditFormStyled,
AtomLabelEditInputStyled,
greekLetters,
primes,
} from './svg_editor.styled.ts';
import type { SvgRendererProps } from './svg_renderer.js';
import { SvgRenderer } from './svg_renderer.js';

Expand Down Expand Up @@ -181,26 +188,6 @@ interface AtomLabelEditFormProps {
onCancel: () => void;
}

const greekLetters = {
alpha: 'α',
beta: 'β',
gamma: 'γ',
delta: 'δ',
epsilon: 'ε',
zeta: 'ζ',
eta: 'η',
theta: 'θ',
} as const;
const greekLetterNames = Object.keys(greekLetters);
const greeksFirstLine = greekLetterNames.slice(0, 6);
const greeksLastLine = greekLetterNames.slice(6);
const primes = {
prime1: '′',
prime2: '″',
prime3: '‴',
};
const primeNames = Object.keys(primes);

function AtomLabelEditForm(props: AtomLabelEditFormProps) {
const { defaultValue, formCoords, onSubmit, onCancel } = props;

Expand Down Expand Up @@ -276,74 +263,58 @@ function AtomLabelEditForm(props: AtomLabelEditFormProps) {
}

return (
<form
<AtomLabelEditFormStyled
ref={formRef}
onSubmit={onFormSubmit}
onKeyDown={onKeyDown}
style={{
position: 'absolute',
top: formCoords.y,
left: formCoords.x,
display: 'grid',
gridTemplateAreas: `
"input input input input submit cancel"
"${greeksFirstLine.join(' ')}"
"${greeksLastLine.join(' ')} . ${primeNames.join(' ')}"
`,
gridTemplateColumns: 'repeat(4, 1.5em)',
alignItems: 'stretch',
gap: '0.25em',
border: '1px solid lightgray',
backgroundColor: 'white',
padding: '0.25em',
}}
style={{ top: formCoords.y, left: formCoords.x }}
>
<input
style={{ gridArea: 'input' }}
<AtomLabelEditInputStyled
type="text"
name="label"
defaultValue={defaultValue}
size={5}
autoFocus
ref={autoSelectText}
/>
<input
style={{ gridArea: 'submit' }}
<AtomLabelEditButtonStyled
area="submit"
type="submit"
value="✔️"
aria-label="Submit"
/>
<button
style={{ gridArea: 'cancel' }}
>
✔️
</AtomLabelEditButtonStyled>
<AtomLabelEditButtonStyled
area="cancel"
type="button"
aria-label="Cancel"
onClick={onCancelClick}
>
</button>
</AtomLabelEditButtonStyled>

{Object.entries(greekLetters).map(([charName, greekChar]) => (
<button
<AtomLabelEditButtonStyled
key={charName}
type="submit"
style={{ gridArea: charName }}
area={charName}
type="button"
onClick={onShortcut}
>
{greekChar}
</button>
</AtomLabelEditButtonStyled>
))}

{Object.entries(primes).map(([primeName, primeChar]) => (
<button
<AtomLabelEditButtonStyled
key={primeName}
type="submit"
style={{ gridArea: primeName }}
area={primeName}
type="button"
onClick={onShortcut}
>
{primeChar}
</button>
</AtomLabelEditButtonStyled>
))}
</form>
</AtomLabelEditFormStyled>
);
}

Expand Down
10 changes: 10 additions & 0 deletions stories/reset/ocl_reset.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { resetCss } from './ocl_reset_css.ts';

// eslint-disable-next-line jsdoc/require-jsdoc
export function OclReset() {
return (
<style href="react-ocl#Reset" precedence="medium">
{resetCss}
</style>
);
}
Loading
Loading