Skip to content

Commit 39e593f

Browse files
committed
feat: toggle buttons ui
1 parent 8341366 commit 39e593f

11 files changed

+171
-23
lines changed

.eslintrc.json

+4-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,10 @@
1717
"files": ["*.tsx"],
1818
"rules": {
1919
"@typescript-eslint/no-non-null-assertion": "off",
20-
"react/no-unknown-property": ["error", { "ignore": ["class", "classList"] }]
20+
"react/no-unknown-property": [
21+
"error",
22+
{ "ignore": ["class", "classList", "stroke-linecap", "stroke-linejoin", "stroke-width"] }
23+
]
2124
}
2225
},
2326
{

packages/astro-content-devtools/src/components/Devtools.tsx

+13-11
Original file line numberDiff line numberDiff line change
@@ -59,17 +59,19 @@ export const Devtools: Component = () => {
5959
>
6060
<ResizeHandle onResize={handleResize} reference={overlay} />
6161
<Panels>
62-
<CollectionsPanel />
63-
<Show when={shouldShowPreviewTypesPanel()}>
64-
<PreviewTypesPanel />
65-
<Switch>
66-
<Match when={shouldShowSchemaPanel()}>
67-
<SchemaPanel />
68-
</Match>
69-
<Match when={shouldShowEntriesPanel()}>
70-
<EntriesPanel />
71-
</Match>
72-
</Switch>
62+
<Show when={isOverlayOpened()}>
63+
<CollectionsPanel />
64+
<Show when={shouldShowPreviewTypesPanel()}>
65+
<PreviewTypesPanel />
66+
<Switch>
67+
<Match when={shouldShowSchemaPanel()}>
68+
<SchemaPanel />
69+
</Match>
70+
<Match when={shouldShowEntriesPanel()}>
71+
<EntriesPanel />
72+
</Match>
73+
</Switch>
74+
</Show>
7375
</Show>
7476
</Panels>
7577
<Show when={!isOverlayOpened()}>
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,71 @@
11
.toggle {
2+
border-radius: var(--acd-rounded-full);
23
cursor: pointer;
34
margin: var(--acd-size-2);
45
pointer-events: all;
56
}
67

78
.closed {
8-
background-color: red;
9+
background-color: var(--acd-color-gray-900);
10+
border: 1px solid var(--acd-color-gray-700);
911
bottom: 0;
12+
box-shadow: 0 1px 2px 0 var(--acd-color-gray-200);
1013
left: 0;
14+
padding: var(--acd-size-2);
1115
position: fixed;
1216
z-index: 99999;
1317
}
1418

19+
.closed:hover {
20+
background-color: var(--acd-color-gray-800);
21+
}
22+
23+
.closed:active {
24+
background-color: var(--acd-color-gray-700);
25+
}
26+
27+
.closed:focus-visible {
28+
outline: 3px solid var(--acd-color-blue-700);
29+
outline-offset: 1px;
30+
}
31+
1532
.opened {
16-
background-color: green;
33+
background-color: var(--acd-color-gray-800);
34+
border: 1px solid var(--acd-color-gray-600);
35+
padding: var(--acd-size-1);
36+
}
37+
38+
.opened:hover {
39+
background-color: var(--acd-color-gray-700);
40+
}
41+
42+
.opened:active {
43+
background-color: var(--acd-color-gray-600);
44+
}
45+
46+
.opened:focus-visible {
47+
outline: 2px solid var(--acd-color-blue-700);
48+
outline-offset: 2px;
49+
}
50+
51+
.icon {
52+
display: block;
53+
color: var(--acd-color-gray-100);
54+
fill: var(--acd-color-gray-100);
55+
}
56+
57+
.toggle:is(:hover, :focus-visible) .icon {
58+
color: var(--acd-color-white);
59+
fill: var(--acd-color-white);
60+
}
61+
62+
.closed .icon {
63+
display: block;
64+
height: var(--acd-icon-size);
65+
width: var(--acd-icon-size);
66+
}
67+
68+
.opened .icon {
69+
height: var(--acd-size-5);
70+
width: var(--acd-size-5);
1771
}

packages/astro-content-devtools/src/components/Toggle.tsx

+50-4
Original file line numberDiff line numberDiff line change
@@ -3,20 +3,66 @@ import { type Component, Show } from 'solid-js'
33
import { useDevtools } from '../hooks/useDevtools'
44

55
import styles from './Toggle.module.css'
6+
import { VisuallyHidden } from './VisuallyHidden'
67

7-
// TODO(HiDeoo) aria
8-
// TODO(HiDeoo) logo
98
export const Toggle: Component = () => {
109
const { isOverlayOpened, toggleOverlay } = useDevtools()
1110

11+
const label = () => `${isOverlayOpened() ? 'Close' : 'Open'} Astro Content Devtools`
12+
1213
return (
1314
<button
15+
aria-controls="AstroContentDevtools"
16+
aria-expanded={isOverlayOpened()}
17+
aria-haspopup="true"
18+
aria-label={label()}
1419
class={styles.toggle}
1520
classList={{ [styles.closed!]: !isOverlayOpened(), [styles.opened!]: isOverlayOpened() }}
1621
onClick={toggleOverlay}
1722
>
18-
<Show when={isOverlayOpened()} fallback="Open">
19-
Close
23+
<Show
24+
when={isOverlayOpened()}
25+
fallback={
26+
<>
27+
<svg
28+
aria-hidden="true"
29+
class={styles.icon}
30+
height="256"
31+
width="256"
32+
viewBox="0 0 256 256"
33+
xmlns="http://www.w3.org/2000/svg"
34+
>
35+
<g>
36+
<path d="M157.589 139.135C181.038 106.838 178.227 61.2684 149.128 32.1657C116.903 -0.055848 64.465 -0.055848 32.2439 32.1657C0.0142429 64.3949 0.0142429 116.825 32.2439 149.054C61.342 178.152 106.912 180.964 139.205 157.519L145.593 163.9L163.974 145.519L157.589 139.135ZM133.102 133.032C109.678 156.452 71.6943 156.456 48.2662 133.032C24.8385 109.604 24.8385 71.6166 48.2662 48.1925C71.6947 24.7684 109.678 24.7684 133.102 48.1925C156.53 71.6166 156.53 109.604 133.102 133.032Z" />
37+
<path d="M233.283 205.023L171.22 149.584L149.666 171.137L205.101 233.205C210.738 240.498 220.888 239.426 230.009 230.305C239.125 221.188 240.58 210.66 233.283 205.023Z" />
38+
<g>
39+
<path d="M74.6395 126.482C69.3922 121.774 67.8605 111.883 70.0466 104.716C73.8372 109.234 79.0894 110.666 84.5297 111.474C92.9283 112.72 101.176 112.254 108.978 108.486C109.871 108.055 110.696 107.481 111.671 106.901C112.403 108.985 112.593 111.09 112.338 113.231C111.716 118.448 109.071 122.477 104.864 125.532C103.182 126.754 101.402 127.846 99.6648 128.998C94.3273 132.539 92.8831 136.69 94.8888 142.73C94.9365 142.877 94.9791 143.024 95.0869 143.383C92.3618 142.186 90.3711 140.443 88.8544 138.151C87.2524 135.733 86.4902 133.057 86.4501 130.162C86.4301 128.753 86.4301 127.332 86.237 125.943C85.7657 122.557 84.1461 121.041 81.0951 120.954C77.9639 120.864 75.4869 122.764 74.83 125.756C74.7799 125.986 74.7072 126.213 74.6345 126.479L74.6395 126.482Z" />
40+
<path d="M48.25 106.91C48.25 106.91 62.5978 99.9758 76.9857 99.9758L87.8337 66.6678C88.2397 65.057 89.4257 63.9624 90.7644 63.9624C92.1032 63.9624 93.289 65.057 93.6952 66.6678L104.543 99.9758C121.583 99.9758 133.279 106.91 133.279 106.91C133.279 106.91 108.908 41.0421 108.86 40.91C108.161 38.9626 106.98 37.7083 105.388 37.7083H76.1434C74.5514 37.7083 73.4182 38.9626 72.671 40.91C72.6184 41.0396 48.25 106.91 48.25 106.91Z" />
41+
</g>
42+
</g>
43+
</svg>
44+
<VisuallyHidden>{label()}</VisuallyHidden>
45+
</>
46+
}
47+
>
48+
<svg
49+
aria-hidden="true"
50+
class={styles.icon}
51+
height="32"
52+
width="32"
53+
viewBox="0 0 16 16"
54+
xmlns="http://www.w3.org/2000/svg"
55+
>
56+
<path
57+
d="m11.25 4.75l-6.5 6.5m0-6.5l6.5 6.5"
58+
fill="none"
59+
stroke="currentColor"
60+
stroke-linecap="round"
61+
stroke-linejoin="round"
62+
stroke-width="1.5"
63+
/>
64+
</svg>
65+
<VisuallyHidden>{label()}</VisuallyHidden>
2066
</Show>
2167
</button>
2268
)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
/* https://github.com/twbs/bootstrap/blob/23e50829f958ea1d741d63e2781716be037e4644/scss/mixins/_visually-hidden.scss */
2+
.hidden {
3+
border: 0px;
4+
clip: rect(0, 0, 0, 0);
5+
height: 1px;
6+
margin: -1px;
7+
overflow: hidden;
8+
padding: 0;
9+
position: absolute;
10+
white-space: nowrap;
11+
width: 1px;
12+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import { type ParentComponent } from 'solid-js'
2+
3+
import styles from './VisuallyHidden.module.css'
4+
5+
export const VisuallyHidden: ParentComponent = (props) => {
6+
return <span class={styles.hidden}>{props.children}</span>
7+
}

packages/astro-content-devtools/src/components/panels/CollectionsPanel.tsx

+3-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,9 @@ export const CollectionsPanel: Component = () => {
1919

2020
return (
2121
<Panel name="collections">
22-
<Toggle />
22+
<Panel.Header>
23+
<Toggle />
24+
</Panel.Header>
2325
<Show
2426
fallback={
2527
<InfoPanel

packages/astro-content-devtools/src/components/panels/Panel.module.css

+7
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
color: var(--acd-color-gray-100);
55
font-size: var(--acd-text-base);
66
overflow-x: hidden;
7+
outline: none;
78
}
89

910
.panel :global(*::selection) {
@@ -16,3 +17,9 @@
1617
margin: 0;
1718
padding: 0;
1819
}
20+
21+
.header {
22+
background-color: var(--acd-color-gray-800);
23+
position: sticky;
24+
top: 0;
25+
}

packages/astro-content-devtools/src/components/panels/Panel.tsx

+9-3
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,21 @@
1-
import { type JSX, type ParentComponent } from 'solid-js'
1+
import { type JSX, type ParentComponent, type ParentProps } from 'solid-js'
22

33
import styles from './Panel.module.css'
44

5-
export const Panel: ParentComponent<PanelProps> = (props) => {
5+
export const Panel = (props: ParentProps<PanelProps>) => {
66
return (
7-
<div class={styles.panel} classList={{ [`acd-panel-${props.name}`]: true }} style={props.style} tabIndex={-1}>
7+
<div class={styles.panel} classList={{ [`acd-panel-${props.name}`]: true }} style={props.style}>
88
{props.children}
99
</div>
1010
)
1111
}
1212

13+
const PanelHeader: ParentComponent = (props) => {
14+
return <header class={styles.header}>{props.children}</header>
15+
}
16+
17+
Panel.Header = PanelHeader
18+
1319
interface PanelProps {
1420
name: string
1521
style?: JSX.CSSProperties | string

packages/astro-content-devtools/src/components/panels/Panels.tsx

+7-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,13 @@ export const Panels: ParentComponent = (props) => {
99
const { isOverlayOpened } = useDevtools()
1010

1111
return (
12-
<div class={styles.panels} classList={{ [styles.opened!]: isOverlayOpened() }}>
12+
<div
13+
aria-hidden={!isOverlayOpened()}
14+
aria-label="Astro Content Devtools"
15+
class={styles.panels}
16+
classList={{ [styles.opened!]: isOverlayOpened() }}
17+
id="AstroContentDevtools"
18+
>
1319
<ErrorBoundary>{props.children}</ErrorBoundary>
1420
</div>
1521
)

packages/astro-content-devtools/src/styles/theme.css

+3
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,10 @@
3434
--acd-size-5: 1.25rem;
3535
--acd-size-7: 1.75rem;
3636

37+
--acd-rounded-full: 9999px;
38+
3739
--acd-duration-150: 150ms;
3840

3941
--acd-panel-width: min(17rem, 15%);
42+
--acd-icon-size: 1.75rem;
4043
}

0 commit comments

Comments
 (0)