@proyecto-viviana/ui 0.1.7 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +192 -0
- package/dist/autocomplete/index.d.ts +89 -0
- package/dist/autocomplete/index.d.ts.map +1 -0
- package/dist/breadcrumbs/index.d.ts +38 -0
- package/dist/breadcrumbs/index.d.ts.map +1 -0
- package/dist/button/Button.d.ts.map +1 -1
- package/dist/calendar/DateField.d.ts +47 -0
- package/dist/calendar/DateField.d.ts.map +1 -0
- package/dist/calendar/DatePicker.d.ts +48 -0
- package/dist/calendar/DatePicker.d.ts.map +1 -0
- package/dist/calendar/RangeCalendar.d.ts +42 -0
- package/dist/calendar/RangeCalendar.d.ts.map +1 -0
- package/dist/calendar/TimeField.d.ts +44 -0
- package/dist/calendar/TimeField.d.ts.map +1 -0
- package/dist/calendar/index.d.ts +50 -0
- package/dist/calendar/index.d.ts.map +1 -0
- package/dist/checkbox/index.d.ts.map +1 -1
- package/dist/color/index.d.ts +228 -0
- package/dist/color/index.d.ts.map +1 -0
- package/dist/combobox/index.d.ts +81 -0
- package/dist/combobox/index.d.ts.map +1 -0
- package/dist/components.css +116 -14
- package/dist/custom/chip/index.d.ts +7 -2
- package/dist/custom/chip/index.d.ts.map +1 -1
- package/dist/custom/event-card/index.d.ts +5 -1
- package/dist/custom/event-card/index.d.ts.map +1 -1
- package/dist/custom/header/index.d.ts +16 -0
- package/dist/custom/header/index.d.ts.map +1 -0
- package/dist/custom/logo/index.d.ts +2 -0
- package/dist/custom/logo/index.d.ts.map +1 -1
- package/dist/custom/page-layout/index.d.ts +2 -0
- package/dist/custom/page-layout/index.d.ts.map +1 -1
- package/dist/custom/profile-card/index.d.ts +5 -1
- package/dist/custom/profile-card/index.d.ts.map +1 -1
- package/dist/custom/timeline-item/index.d.ts +12 -2
- package/dist/custom/timeline-item/index.d.ts.map +1 -1
- package/dist/dialog/Dialog.d.ts +67 -0
- package/dist/dialog/Dialog.d.ts.map +1 -0
- package/dist/dialog/index.d.ts +2 -17
- package/dist/dialog/index.d.ts.map +1 -1
- package/dist/disclosure/index.d.ts +84 -0
- package/dist/disclosure/index.d.ts.map +1 -0
- package/dist/gridlist/index.d.ts +92 -0
- package/dist/gridlist/index.d.ts.map +1 -0
- package/dist/index.d.ts +58 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6984 -783
- package/dist/index.js.map +1 -1
- package/dist/index.ssr.js +5905 -571
- package/dist/index.ssr.js.map +1 -1
- package/dist/landmark/index.d.ts +83 -0
- package/dist/landmark/index.d.ts.map +1 -0
- package/dist/link/index.d.ts.map +1 -1
- package/dist/listbox/index.d.ts +47 -0
- package/dist/listbox/index.d.ts.map +1 -0
- package/dist/menu/index.d.ts +74 -0
- package/dist/menu/index.d.ts.map +1 -0
- package/dist/meter/index.d.ts +49 -0
- package/dist/meter/index.d.ts.map +1 -0
- package/dist/numberfield/index.d.ts +50 -0
- package/dist/numberfield/index.d.ts.map +1 -0
- package/dist/popover/index.d.ts +85 -0
- package/dist/popover/index.d.ts.map +1 -0
- package/dist/radio/index.d.ts +7 -4
- package/dist/radio/index.d.ts.map +1 -1
- package/dist/searchfield/index.d.ts +44 -0
- package/dist/searchfield/index.d.ts.map +1 -0
- package/dist/select/index.d.ts +72 -0
- package/dist/select/index.d.ts.map +1 -0
- package/dist/slider/index.d.ts +53 -0
- package/dist/slider/index.d.ts.map +1 -0
- package/dist/switch/ToggleSwitch.d.ts.map +1 -1
- package/dist/table/index.d.ts +140 -0
- package/dist/table/index.d.ts.map +1 -0
- package/dist/tabs/index.d.ts +56 -0
- package/dist/tabs/index.d.ts.map +1 -0
- package/dist/tag-group/index.d.ts +80 -0
- package/dist/tag-group/index.d.ts.map +1 -0
- package/dist/toast/index.d.ts +101 -0
- package/dist/toast/index.d.ts.map +1 -0
- package/dist/toolbar/index.d.ts +42 -0
- package/dist/toolbar/index.d.ts.map +1 -0
- package/dist/tooltip/index.d.ts +66 -5
- package/dist/tooltip/index.d.ts.map +1 -1
- package/dist/tree/index.d.ts +99 -0
- package/dist/tree/index.d.ts.map +1 -0
- package/package.json +66 -58
- package/src/autocomplete/index.tsx +313 -0
- package/src/breadcrumbs/index.tsx +207 -0
- package/src/button/Button.tsx +74 -75
- package/src/calendar/DateField.tsx +200 -0
- package/src/calendar/DatePicker.tsx +298 -0
- package/src/calendar/RangeCalendar.tsx +236 -0
- package/src/calendar/TimeField.tsx +196 -0
- package/src/calendar/index.tsx +223 -0
- package/src/checkbox/index.tsx +3 -4
- package/src/color/index.tsx +687 -0
- package/src/combobox/index.tsx +383 -0
- package/src/components.css +116 -14
- package/src/custom/chip/index.tsx +17 -3
- package/src/custom/event-card/index.tsx +8 -2
- package/src/custom/header/index.tsx +33 -0
- package/src/custom/logo/index.tsx +7 -3
- package/src/custom/page-layout/index.tsx +12 -3
- package/src/custom/profile-card/index.tsx +8 -2
- package/src/custom/timeline-item/index.tsx +28 -4
- package/src/dialog/Dialog.tsx +260 -0
- package/src/dialog/index.tsx +3 -69
- package/src/disclosure/index.tsx +307 -0
- package/src/gridlist/index.tsx +403 -0
- package/src/index.ts +219 -4
- package/src/landmark/index.tsx +231 -0
- package/src/link/index.tsx +1 -2
- package/src/listbox/index.tsx +231 -0
- package/src/menu/index.tsx +297 -0
- package/src/meter/index.tsx +163 -0
- package/src/numberfield/index.tsx +482 -0
- package/src/popover/index.tsx +260 -0
- package/src/radio/index.tsx +36 -82
- package/src/searchfield/index.tsx +453 -0
- package/src/select/index.tsx +349 -0
- package/src/slider/index.tsx +382 -0
- package/src/switch/ToggleSwitch.tsx +1 -2
- package/src/table/index.tsx +531 -0
- package/src/tabs/index.tsx +273 -0
- package/src/tag-group/index.tsx +240 -0
- package/src/toast/index.tsx +324 -0
- package/src/toolbar/index.tsx +108 -0
- package/src/tooltip/index.tsx +171 -5
- package/src/tree/index.tsx +494 -0
package/src/index.ts
CHANGED
|
@@ -31,16 +31,20 @@ export { RadioGroup, Radio } from './radio';
|
|
|
31
31
|
export type { RadioGroupProps, RadioProps, RadioGroupOrientation, RadioGroupSize } from './radio';
|
|
32
32
|
|
|
33
33
|
// Dialog
|
|
34
|
-
export { Dialog } from './dialog';
|
|
35
|
-
export type { DialogProps } from './dialog';
|
|
34
|
+
export { Dialog, DialogTrigger, DialogFooter } from './dialog';
|
|
35
|
+
export type { DialogProps, DialogTriggerProps, DialogFooterProps, DialogSize } from './dialog';
|
|
36
36
|
|
|
37
37
|
// Icon
|
|
38
38
|
export { Icon, GitHubIcon } from './icon';
|
|
39
39
|
export type { IconProps, GitHubIconProps } from './icon';
|
|
40
40
|
|
|
41
41
|
// Tooltip
|
|
42
|
-
export { Tooltip } from './tooltip';
|
|
43
|
-
export type { TooltipProps } from './tooltip';
|
|
42
|
+
export { Tooltip, TooltipTrigger, SimpleTooltip } from './tooltip';
|
|
43
|
+
export type { TooltipProps, TooltipTriggerProps, TooltipPlacement, TooltipVariant, SimpleTooltipProps } from './tooltip';
|
|
44
|
+
|
|
45
|
+
// Popover
|
|
46
|
+
export { Popover, PopoverTrigger, PopoverHeader, PopoverFooter } from './popover';
|
|
47
|
+
export type { PopoverProps, PopoverTriggerProps, PopoverHeaderProps, PopoverFooterProps, PopoverPlacement, PopoverSize, PopoverRenderProps } from './popover';
|
|
44
48
|
|
|
45
49
|
// TextField
|
|
46
50
|
export { TextField } from './textfield';
|
|
@@ -58,6 +62,213 @@ export type { ProgressBarProps, ProgressBarSize, ProgressBarVariant } from './pr
|
|
|
58
62
|
export { Separator } from './separator';
|
|
59
63
|
export type { SeparatorProps, SeparatorVariant, SeparatorSize } from './separator';
|
|
60
64
|
|
|
65
|
+
// Toolbar
|
|
66
|
+
export { Toolbar } from './toolbar';
|
|
67
|
+
export type { ToolbarProps, ToolbarSize, ToolbarVariant } from './toolbar';
|
|
68
|
+
|
|
69
|
+
// Autocomplete
|
|
70
|
+
export { SearchAutocomplete } from './autocomplete';
|
|
71
|
+
export type { SearchAutocompleteProps, SearchAutocompleteItem, SearchAutocompleteSize } from './autocomplete';
|
|
72
|
+
|
|
73
|
+
// Select
|
|
74
|
+
export { Select, SelectTrigger, SelectValue, SelectListBox, SelectOption } from './select';
|
|
75
|
+
export type { SelectProps, SelectTriggerProps, SelectValueProps, SelectListBoxProps, SelectOptionProps, SelectSize } from './select';
|
|
76
|
+
|
|
77
|
+
// Menu
|
|
78
|
+
export { Menu, MenuItem, MenuTrigger, MenuButton, MenuSeparator } from './menu';
|
|
79
|
+
export type { MenuProps, MenuItemProps, MenuTriggerProps, MenuButtonProps, MenuSeparatorProps, MenuSize } from './menu';
|
|
80
|
+
|
|
81
|
+
// ListBox
|
|
82
|
+
export { ListBox, ListBoxOption } from './listbox';
|
|
83
|
+
export type { ListBoxProps, ListBoxOptionProps, ListBoxSize } from './listbox';
|
|
84
|
+
|
|
85
|
+
// Tabs
|
|
86
|
+
export { Tabs, TabList, Tab, TabPanel } from './tabs';
|
|
87
|
+
export type { TabsProps, TabListProps, TabProps, TabPanelProps, TabsSize, TabsVariant, TabOrientation } from './tabs';
|
|
88
|
+
|
|
89
|
+
// Breadcrumbs
|
|
90
|
+
export { Breadcrumbs, BreadcrumbItem } from './breadcrumbs';
|
|
91
|
+
export type { BreadcrumbsProps, BreadcrumbItemProps, BreadcrumbsSize, BreadcrumbsVariant } from './breadcrumbs';
|
|
92
|
+
|
|
93
|
+
// NumberField
|
|
94
|
+
export { NumberField } from './numberfield';
|
|
95
|
+
export type { NumberFieldProps, NumberFieldSize, NumberFieldVariant } from './numberfield';
|
|
96
|
+
|
|
97
|
+
// SearchField
|
|
98
|
+
export { SearchField } from './searchfield';
|
|
99
|
+
export type { SearchFieldProps, SearchFieldSize, SearchFieldVariant } from './searchfield';
|
|
100
|
+
|
|
101
|
+
// Slider
|
|
102
|
+
export { Slider } from './slider';
|
|
103
|
+
export type { SliderProps, SliderSize, SliderVariant } from './slider';
|
|
104
|
+
|
|
105
|
+
// ComboBox
|
|
106
|
+
export { ComboBox, ComboBoxInputGroup, ComboBoxInput, ComboBoxButton, ComboBoxListBox, ComboBoxOption, defaultContainsFilter } from './combobox';
|
|
107
|
+
export type { ComboBoxProps, ComboBoxInputProps, ComboBoxButtonProps, ComboBoxListBoxProps, ComboBoxOptionProps, ComboBoxSize, FilterFn, MenuTriggerAction } from './combobox';
|
|
108
|
+
|
|
109
|
+
// Toast
|
|
110
|
+
export {
|
|
111
|
+
Toast,
|
|
112
|
+
ToastRegion,
|
|
113
|
+
ToastProvider,
|
|
114
|
+
ToastContext,
|
|
115
|
+
addToast,
|
|
116
|
+
toastSuccess,
|
|
117
|
+
toastError,
|
|
118
|
+
toastWarning,
|
|
119
|
+
toastInfo,
|
|
120
|
+
globalToastQueue,
|
|
121
|
+
useToastContext,
|
|
122
|
+
} from './toast';
|
|
123
|
+
export type {
|
|
124
|
+
ToastProps,
|
|
125
|
+
ToastRegionProps,
|
|
126
|
+
ToastProviderProps,
|
|
127
|
+
ToastPlacement,
|
|
128
|
+
ToastVariant,
|
|
129
|
+
ToastContent,
|
|
130
|
+
ToastRenderProps,
|
|
131
|
+
ToastRegionRenderProps,
|
|
132
|
+
QueuedToast,
|
|
133
|
+
ToastOptions,
|
|
134
|
+
} from './toast';
|
|
135
|
+
|
|
136
|
+
// Disclosure
|
|
137
|
+
export {
|
|
138
|
+
Disclosure,
|
|
139
|
+
DisclosureGroup,
|
|
140
|
+
DisclosureTrigger,
|
|
141
|
+
DisclosurePanel,
|
|
142
|
+
} from './disclosure';
|
|
143
|
+
export type {
|
|
144
|
+
DisclosureProps,
|
|
145
|
+
DisclosureGroupProps,
|
|
146
|
+
DisclosureTriggerProps,
|
|
147
|
+
DisclosurePanelProps,
|
|
148
|
+
DisclosureSize,
|
|
149
|
+
DisclosureVariant,
|
|
150
|
+
} from './disclosure';
|
|
151
|
+
|
|
152
|
+
// Meter
|
|
153
|
+
export { Meter } from './meter';
|
|
154
|
+
export type { MeterProps, MeterSize, MeterVariant } from './meter';
|
|
155
|
+
|
|
156
|
+
// TagGroup
|
|
157
|
+
export { TagGroup } from './tag-group';
|
|
158
|
+
export type { TagGroupProps, TagProps, TagGroupSize, TagGroupVariant } from './tag-group';
|
|
159
|
+
|
|
160
|
+
// Calendar
|
|
161
|
+
export { Calendar } from './calendar';
|
|
162
|
+
export type { CalendarProps, CalendarSize, CalendarDate, DateValue } from './calendar';
|
|
163
|
+
|
|
164
|
+
// RangeCalendar
|
|
165
|
+
export { RangeCalendar } from './calendar/RangeCalendar';
|
|
166
|
+
export type { RangeCalendarProps, RangeCalendarSize, RangeValue } from './calendar/RangeCalendar';
|
|
167
|
+
|
|
168
|
+
// DateField
|
|
169
|
+
export { DateField } from './calendar/DateField';
|
|
170
|
+
export type { DateFieldProps, DateFieldSize } from './calendar/DateField';
|
|
171
|
+
|
|
172
|
+
// TimeField
|
|
173
|
+
export { TimeField } from './calendar/TimeField';
|
|
174
|
+
export type { TimeFieldProps, TimeFieldSize, TimeValue } from './calendar/TimeField';
|
|
175
|
+
|
|
176
|
+
// DatePicker
|
|
177
|
+
export { DatePicker } from './calendar/DatePicker';
|
|
178
|
+
export type { DatePickerProps, DatePickerSize } from './calendar/DatePicker';
|
|
179
|
+
|
|
180
|
+
// Table
|
|
181
|
+
export {
|
|
182
|
+
Table,
|
|
183
|
+
TableHeader,
|
|
184
|
+
TableColumn,
|
|
185
|
+
TableBody,
|
|
186
|
+
TableRow,
|
|
187
|
+
TableCell,
|
|
188
|
+
TableSelectionCheckbox,
|
|
189
|
+
TableSelectAllCheckbox,
|
|
190
|
+
} from './table';
|
|
191
|
+
export type {
|
|
192
|
+
TableProps,
|
|
193
|
+
TableHeaderProps,
|
|
194
|
+
TableColumnProps,
|
|
195
|
+
TableBodyProps,
|
|
196
|
+
TableRowProps,
|
|
197
|
+
TableCellProps,
|
|
198
|
+
TableSize,
|
|
199
|
+
TableVariant,
|
|
200
|
+
} from './table';
|
|
201
|
+
|
|
202
|
+
// GridList
|
|
203
|
+
export {
|
|
204
|
+
GridList,
|
|
205
|
+
GridListItem,
|
|
206
|
+
GridListSelectionCheckbox,
|
|
207
|
+
} from './gridlist';
|
|
208
|
+
export type {
|
|
209
|
+
GridListProps,
|
|
210
|
+
GridListItemProps,
|
|
211
|
+
GridListSize,
|
|
212
|
+
GridListVariant,
|
|
213
|
+
GridListLayout,
|
|
214
|
+
} from './gridlist';
|
|
215
|
+
|
|
216
|
+
// Tree
|
|
217
|
+
export {
|
|
218
|
+
Tree,
|
|
219
|
+
TreeItem,
|
|
220
|
+
TreeExpandButton,
|
|
221
|
+
TreeSelectionCheckbox,
|
|
222
|
+
} from './tree';
|
|
223
|
+
export type {
|
|
224
|
+
TreeProps,
|
|
225
|
+
TreeItemProps,
|
|
226
|
+
TreeExpandButtonProps,
|
|
227
|
+
TreeSize,
|
|
228
|
+
TreeVariant,
|
|
229
|
+
} from './tree';
|
|
230
|
+
|
|
231
|
+
// Color
|
|
232
|
+
export {
|
|
233
|
+
ColorSlider,
|
|
234
|
+
ColorSliderTrack,
|
|
235
|
+
ColorSliderThumb,
|
|
236
|
+
ColorArea,
|
|
237
|
+
ColorAreaGradient,
|
|
238
|
+
ColorAreaThumb,
|
|
239
|
+
ColorWheel,
|
|
240
|
+
ColorWheelTrack,
|
|
241
|
+
ColorWheelThumb,
|
|
242
|
+
ColorField,
|
|
243
|
+
ColorFieldInput,
|
|
244
|
+
ColorSwatch,
|
|
245
|
+
ColorPicker,
|
|
246
|
+
} from './color';
|
|
247
|
+
export type {
|
|
248
|
+
ColorSliderProps,
|
|
249
|
+
ColorAreaProps,
|
|
250
|
+
ColorWheelProps,
|
|
251
|
+
ColorFieldProps,
|
|
252
|
+
ColorSwatchProps,
|
|
253
|
+
ColorPickerProps,
|
|
254
|
+
ColorSize,
|
|
255
|
+
} from './color';
|
|
256
|
+
|
|
257
|
+
// Landmark
|
|
258
|
+
export {
|
|
259
|
+
Landmark,
|
|
260
|
+
SkipLink,
|
|
261
|
+
LandmarkNavigator,
|
|
262
|
+
useLandmarkController,
|
|
263
|
+
} from './landmark';
|
|
264
|
+
export type {
|
|
265
|
+
LandmarkProps,
|
|
266
|
+
SkipLinkProps,
|
|
267
|
+
LandmarkNavigatorProps,
|
|
268
|
+
AriaLandmarkRole,
|
|
269
|
+
LandmarkController,
|
|
270
|
+
} from './landmark';
|
|
271
|
+
|
|
61
272
|
// ============================================
|
|
62
273
|
// CUSTOM COMPONENTS
|
|
63
274
|
// ============================================
|
|
@@ -70,6 +281,10 @@ export type { ChipProps, ChipVariant } from './custom/chip';
|
|
|
70
281
|
export { NavHeader } from './custom/nav-header';
|
|
71
282
|
export type { NavHeaderProps } from './custom/nav-header';
|
|
72
283
|
|
|
284
|
+
// Header
|
|
285
|
+
export { Header } from './custom/header';
|
|
286
|
+
export type { HeaderProps } from './custom/header';
|
|
287
|
+
|
|
73
288
|
// LateralNav
|
|
74
289
|
export { LateralNav, NavItem, NavLink, NavSection } from './custom/lateral-nav';
|
|
75
290
|
export type { LateralNavProps, NavItemProps, NavLinkProps, NavSectionProps } from './custom/lateral-nav';
|
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Landmark component for proyecto-viviana-ui
|
|
3
|
+
*
|
|
4
|
+
* Styled landmark component built on top of solidaria-components.
|
|
5
|
+
* Landmarks help screen reader users navigate between major sections of a page.
|
|
6
|
+
* Press F6 to cycle through landmarks, or Shift+F6 to go backwards.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import { type JSX, splitProps, Show } from 'solid-js'
|
|
10
|
+
import {
|
|
11
|
+
Landmark as HeadlessLandmark,
|
|
12
|
+
useLandmarkController,
|
|
13
|
+
type LandmarkProps as HeadlessLandmarkProps,
|
|
14
|
+
type AriaLandmarkRole,
|
|
15
|
+
type LandmarkController,
|
|
16
|
+
} from '@proyecto-viviana/solidaria-components'
|
|
17
|
+
|
|
18
|
+
// ============================================
|
|
19
|
+
// TYPES
|
|
20
|
+
// ============================================
|
|
21
|
+
|
|
22
|
+
export interface LandmarkProps extends Omit<HeadlessLandmarkProps, 'class' | 'style'> {
|
|
23
|
+
/** Additional CSS class name. */
|
|
24
|
+
class?: string
|
|
25
|
+
/** Whether to show a visual indicator (for development). */
|
|
26
|
+
showLabel?: boolean
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export type { AriaLandmarkRole, LandmarkController }
|
|
30
|
+
|
|
31
|
+
// ============================================
|
|
32
|
+
// STYLES
|
|
33
|
+
// ============================================
|
|
34
|
+
|
|
35
|
+
const roleLabels: Record<AriaLandmarkRole, string> = {
|
|
36
|
+
main: 'Main',
|
|
37
|
+
navigation: 'Navigation',
|
|
38
|
+
search: 'Search',
|
|
39
|
+
banner: 'Banner',
|
|
40
|
+
contentinfo: 'Footer',
|
|
41
|
+
complementary: 'Aside',
|
|
42
|
+
form: 'Form',
|
|
43
|
+
region: 'Region',
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
const roleColors: Record<AriaLandmarkRole, string> = {
|
|
47
|
+
main: 'bg-accent/10 border-accent-300',
|
|
48
|
+
navigation: 'bg-primary-500/10 border-primary-400',
|
|
49
|
+
search: 'bg-warning-400/10 border-warning-400',
|
|
50
|
+
banner: 'bg-success-400/10 border-success-400',
|
|
51
|
+
contentinfo: 'bg-danger-400/10 border-danger-400',
|
|
52
|
+
complementary: 'bg-primary-300/10 border-primary-300',
|
|
53
|
+
form: 'bg-accent-200/10 border-accent-200',
|
|
54
|
+
region: 'bg-bg-200/50 border-bg-300',
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// ============================================
|
|
58
|
+
// LANDMARK COMPONENT
|
|
59
|
+
// ============================================
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* A landmark is a region of the page that helps screen reader users navigate.
|
|
63
|
+
* Press F6 to cycle through landmarks, or Shift+F6 to go backwards.
|
|
64
|
+
*
|
|
65
|
+
* @example
|
|
66
|
+
* ```tsx
|
|
67
|
+
* // Main content area
|
|
68
|
+
* <Landmark role="main" aria-label="Main content">
|
|
69
|
+
* <h1>Welcome</h1>
|
|
70
|
+
* <p>Page content here...</p>
|
|
71
|
+
* </Landmark>
|
|
72
|
+
*
|
|
73
|
+
* // Navigation
|
|
74
|
+
* <Landmark role="navigation" aria-label="Primary navigation">
|
|
75
|
+
* <nav>...</nav>
|
|
76
|
+
* </Landmark>
|
|
77
|
+
*
|
|
78
|
+
* // With development label visible
|
|
79
|
+
* <Landmark role="main" aria-label="Main content" showLabel>
|
|
80
|
+
* ...
|
|
81
|
+
* </Landmark>
|
|
82
|
+
* ```
|
|
83
|
+
*/
|
|
84
|
+
export function Landmark(props: LandmarkProps): JSX.Element {
|
|
85
|
+
const [local, headlessProps] = splitProps(props, ['class', 'showLabel'])
|
|
86
|
+
const customClass = local.class ?? ''
|
|
87
|
+
|
|
88
|
+
const role = () => headlessProps.role
|
|
89
|
+
|
|
90
|
+
const getClassName = (): string => {
|
|
91
|
+
const base = 'relative'
|
|
92
|
+
const debugClass = local.showLabel
|
|
93
|
+
? `border-2 border-dashed ${roleColors[role()]}`
|
|
94
|
+
: ''
|
|
95
|
+
return [base, debugClass, customClass].filter(Boolean).join(' ')
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
return (
|
|
99
|
+
<HeadlessLandmark {...headlessProps} class={getClassName()}>
|
|
100
|
+
<Show when={local.showLabel}>
|
|
101
|
+
<div
|
|
102
|
+
class={`absolute -top-3 left-2 px-2 py-0.5 text-xs font-medium rounded ${roleColors[role()]} text-primary-200`}
|
|
103
|
+
>
|
|
104
|
+
{roleLabels[role()]}
|
|
105
|
+
<Show when={headlessProps['aria-label']}>
|
|
106
|
+
<span class="text-primary-400"> - {headlessProps['aria-label']}</span>
|
|
107
|
+
</Show>
|
|
108
|
+
</div>
|
|
109
|
+
</Show>
|
|
110
|
+
{props.children}
|
|
111
|
+
</HeadlessLandmark>
|
|
112
|
+
)
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
// ============================================
|
|
116
|
+
// SKIP LINK COMPONENT
|
|
117
|
+
// ============================================
|
|
118
|
+
|
|
119
|
+
export interface SkipLinkProps {
|
|
120
|
+
/** The ID of the element to skip to (usually the main landmark). */
|
|
121
|
+
href: string
|
|
122
|
+
/** The text to display in the skip link. */
|
|
123
|
+
children?: JSX.Element
|
|
124
|
+
/** Additional CSS class name. */
|
|
125
|
+
class?: string
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* A skip link allows keyboard users to bypass repetitive navigation and jump directly to main content.
|
|
130
|
+
* The link is visually hidden until focused.
|
|
131
|
+
*
|
|
132
|
+
* @example
|
|
133
|
+
* ```tsx
|
|
134
|
+
* <SkipLink href="#main-content">Skip to main content</SkipLink>
|
|
135
|
+
*
|
|
136
|
+
* <Landmark role="navigation">...</Landmark>
|
|
137
|
+
*
|
|
138
|
+
* <Landmark role="main" id="main-content">
|
|
139
|
+
* ...
|
|
140
|
+
* </Landmark>
|
|
141
|
+
* ```
|
|
142
|
+
*/
|
|
143
|
+
export function SkipLink(props: SkipLinkProps): JSX.Element {
|
|
144
|
+
const customClass = props.class ?? ''
|
|
145
|
+
|
|
146
|
+
const className = [
|
|
147
|
+
// Visually hidden by default
|
|
148
|
+
'absolute left-0 top-0 -translate-y-full',
|
|
149
|
+
// Show when focused
|
|
150
|
+
'focus:translate-y-0',
|
|
151
|
+
// Styling
|
|
152
|
+
'z-50 px-4 py-2 bg-accent text-white font-medium rounded-br-lg',
|
|
153
|
+
'transition-transform duration-200',
|
|
154
|
+
'focus:outline-none focus:ring-2 focus:ring-accent-300 focus:ring-offset-2',
|
|
155
|
+
customClass,
|
|
156
|
+
]
|
|
157
|
+
.filter(Boolean)
|
|
158
|
+
.join(' ')
|
|
159
|
+
|
|
160
|
+
return (
|
|
161
|
+
<a href={props.href} class={className}>
|
|
162
|
+
{props.children ?? 'Skip to main content'}
|
|
163
|
+
</a>
|
|
164
|
+
)
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
// ============================================
|
|
168
|
+
// LANDMARK NAVIGATOR COMPONENT
|
|
169
|
+
// ============================================
|
|
170
|
+
|
|
171
|
+
export interface LandmarkNavigatorProps {
|
|
172
|
+
/** Additional CSS class name. */
|
|
173
|
+
class?: string
|
|
174
|
+
/** Whether to show the navigator (for development/accessibility testing). */
|
|
175
|
+
isVisible?: boolean
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
/**
|
|
179
|
+
* A floating navigator for landmarks, useful for development and accessibility testing.
|
|
180
|
+
* Provides buttons to navigate between landmarks programmatically.
|
|
181
|
+
*
|
|
182
|
+
* @example
|
|
183
|
+
* ```tsx
|
|
184
|
+
* // Show in development only
|
|
185
|
+
* <LandmarkNavigator isVisible={import.meta.env.DEV} />
|
|
186
|
+
* ```
|
|
187
|
+
*/
|
|
188
|
+
export function LandmarkNavigator(props: LandmarkNavigatorProps): JSX.Element {
|
|
189
|
+
const controller = useLandmarkController()
|
|
190
|
+
|
|
191
|
+
return (
|
|
192
|
+
<Show when={props.isVisible}>
|
|
193
|
+
<div
|
|
194
|
+
class={`fixed bottom-4 right-4 z-50 flex flex-col gap-2 p-3 bg-bg-400 border border-bg-300 rounded-lg shadow-lg ${props.class ?? ''}`}
|
|
195
|
+
>
|
|
196
|
+
<span class="text-xs font-medium text-primary-400 uppercase tracking-wider">
|
|
197
|
+
Landmarks (F6)
|
|
198
|
+
</span>
|
|
199
|
+
<div class="flex gap-1">
|
|
200
|
+
<button
|
|
201
|
+
type="button"
|
|
202
|
+
onClick={() => controller.focusPrevious()}
|
|
203
|
+
class="px-2 py-1 text-sm bg-bg-300 hover:bg-bg-200 text-primary-200 rounded transition-colors"
|
|
204
|
+
title="Previous landmark (Shift+F6)"
|
|
205
|
+
>
|
|
206
|
+
←
|
|
207
|
+
</button>
|
|
208
|
+
<button
|
|
209
|
+
type="button"
|
|
210
|
+
onClick={() => controller.focusMain()}
|
|
211
|
+
class="px-3 py-1 text-sm bg-accent hover:bg-accent-200 text-white rounded transition-colors"
|
|
212
|
+
title="Go to main content"
|
|
213
|
+
>
|
|
214
|
+
Main
|
|
215
|
+
</button>
|
|
216
|
+
<button
|
|
217
|
+
type="button"
|
|
218
|
+
onClick={() => controller.focusNext()}
|
|
219
|
+
class="px-2 py-1 text-sm bg-bg-300 hover:bg-bg-200 text-primary-200 rounded transition-colors"
|
|
220
|
+
title="Next landmark (F6)"
|
|
221
|
+
>
|
|
222
|
+
→
|
|
223
|
+
</button>
|
|
224
|
+
</div>
|
|
225
|
+
</div>
|
|
226
|
+
</Show>
|
|
227
|
+
)
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
// Export controller hook for convenience
|
|
231
|
+
export { useLandmarkController }
|
package/src/link/index.tsx
CHANGED
|
@@ -67,7 +67,6 @@ export function Link(props: LinkProps): JSX.Element {
|
|
|
67
67
|
'isStandalone',
|
|
68
68
|
'isQuiet',
|
|
69
69
|
'class',
|
|
70
|
-
'children',
|
|
71
70
|
]);
|
|
72
71
|
|
|
73
72
|
const variant = local.variant ?? 'primary';
|
|
@@ -125,7 +124,7 @@ export function Link(props: LinkProps): JSX.Element {
|
|
|
125
124
|
{...headlessProps}
|
|
126
125
|
class={getClassName}
|
|
127
126
|
>
|
|
128
|
-
{
|
|
127
|
+
{props.children}
|
|
129
128
|
</HeadlessLink>
|
|
130
129
|
);
|
|
131
130
|
}
|