@proyecto-viviana/ui 0.3.5 → 0.4.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/LICENSE +21 -0
- package/README.md +80 -157
- package/dist/ActionButton.d.ts +2 -0
- package/dist/ActionButton.d.ts.map +1 -0
- package/dist/ActionButton.js +1 -0
- package/dist/ActionButton.jsx +1 -0
- package/dist/ActionMenu.d.ts +2 -0
- package/dist/ActionMenu.d.ts.map +1 -0
- package/dist/ActionMenu.js +1 -0
- package/dist/ActionMenu.jsx +1 -0
- package/dist/Breadcrumbs.d.ts +2 -0
- package/dist/Breadcrumbs.d.ts.map +1 -0
- package/dist/Breadcrumbs.js +1 -0
- package/dist/Breadcrumbs.jsx +1 -0
- package/dist/Button.d.ts +2 -0
- package/dist/Button.d.ts.map +1 -0
- package/dist/Button.js +1 -0
- package/dist/Button.jsx +1 -0
- package/dist/Calendar.d.ts +2 -0
- package/dist/Calendar.d.ts.map +1 -0
- package/dist/Calendar.js +1 -0
- package/dist/Calendar.jsx +1 -0
- package/dist/CalendarCard.d.ts +2 -0
- package/dist/CalendarCard.d.ts.map +1 -0
- package/dist/CalendarCard.js +97 -0
- package/dist/CalendarCard.js.map +1 -0
- package/dist/CalendarCard.jsx +51 -0
- package/dist/CalendarCard.jsx.map +1 -0
- package/dist/Card.d.ts +2 -0
- package/dist/Card.d.ts.map +1 -0
- package/dist/Card.js +1 -0
- package/dist/Card.jsx +1 -0
- package/dist/CardView.d.ts +2 -0
- package/dist/CardView.d.ts.map +1 -0
- package/dist/CardView.js +1 -0
- package/dist/CardView.jsx +1 -0
- package/dist/CenterBaseline.d.ts +2 -0
- package/dist/CenterBaseline.d.ts.map +1 -0
- package/dist/CenterBaseline.js +1 -0
- package/dist/CenterBaseline.jsx +1 -0
- package/dist/Chip.d.ts +2 -0
- package/dist/Chip.d.ts.map +1 -0
- package/dist/Chip.js +2 -0
- package/dist/Chip.jsx +2 -0
- package/dist/ColorArea.d.ts +2 -0
- package/dist/ColorArea.d.ts.map +1 -0
- package/dist/ColorArea.js +1 -0
- package/dist/ColorArea.jsx +1 -0
- package/dist/ColorField.d.ts +2 -0
- package/dist/ColorField.d.ts.map +1 -0
- package/dist/ColorField.js +1 -0
- package/dist/ColorField.jsx +1 -0
- package/dist/ColorSlider.d.ts +2 -0
- package/dist/ColorSlider.d.ts.map +1 -0
- package/dist/ColorSlider.js +1 -0
- package/dist/ColorSlider.jsx +1 -0
- package/dist/ColorSwatch.d.ts +2 -0
- package/dist/ColorSwatch.d.ts.map +1 -0
- package/dist/ColorSwatch.js +1 -0
- package/dist/ColorSwatch.jsx +1 -0
- package/dist/ColorSwatchPicker.d.ts +2 -0
- package/dist/ColorSwatchPicker.d.ts.map +1 -0
- package/dist/ColorSwatchPicker.js +1 -0
- package/dist/ColorSwatchPicker.jsx +1 -0
- package/dist/ColorWheel.d.ts +2 -0
- package/dist/ColorWheel.d.ts.map +1 -0
- package/dist/ColorWheel.js +1 -0
- package/dist/ColorWheel.jsx +1 -0
- package/dist/ContrastIcon.d.ts +3 -0
- package/dist/ContrastIcon.d.ts.map +1 -0
- package/dist/ContrastIcon.js +3 -0
- package/dist/ContrastIcon.jsx +3 -0
- package/dist/Conversation.d.ts +2 -0
- package/dist/Conversation.d.ts.map +1 -0
- package/dist/Conversation.js +177 -0
- package/dist/Conversation.js.map +1 -0
- package/dist/Conversation.jsx +107 -0
- package/dist/Conversation.jsx.map +1 -0
- package/dist/Disclosure.d.ts +2 -0
- package/dist/Disclosure.d.ts.map +1 -0
- package/dist/Disclosure.js +1 -0
- package/dist/Disclosure.jsx +1 -0
- package/dist/EventCard.d.ts +2 -0
- package/dist/EventCard.d.ts.map +1 -0
- package/dist/EventCard.js +173 -0
- package/dist/EventCard.js.map +1 -0
- package/dist/EventCard.jsx +96 -0
- package/dist/EventCard.jsx.map +1 -0
- package/dist/FileTrigger.d.ts +2 -0
- package/dist/FileTrigger.d.ts.map +1 -0
- package/dist/FileTrigger.js +1 -0
- package/dist/FileTrigger.jsx +1 -0
- package/dist/GitHubIcon.d.ts +2 -0
- package/dist/GitHubIcon.d.ts.map +1 -0
- package/dist/GitHubIcon.js +1 -0
- package/dist/GitHubIcon.jsx +1 -0
- package/dist/LightenIcon.d.ts +3 -0
- package/dist/LightenIcon.d.ts.map +1 -0
- package/dist/LightenIcon.js +3 -0
- package/dist/LightenIcon.jsx +3 -0
- package/dist/LinkButton.d.ts +2 -0
- package/dist/LinkButton.d.ts.map +1 -0
- package/dist/LinkButton.js +1 -0
- package/dist/LinkButton.jsx +1 -0
- package/dist/ListView.d.ts +2 -0
- package/dist/ListView.d.ts.map +1 -0
- package/dist/ListView.js +1 -0
- package/dist/ListView.jsx +1 -0
- package/dist/Logo.d.ts +2 -0
- package/dist/Logo.d.ts.map +1 -0
- package/dist/Logo.js +116 -0
- package/dist/Logo.js.map +1 -0
- package/dist/Logo.jsx +101 -0
- package/dist/Logo.jsx.map +1 -0
- package/dist/Menu.d.ts +2 -0
- package/dist/Menu.d.ts.map +1 -0
- package/dist/Menu.js +1 -0
- package/dist/Menu.jsx +1 -0
- package/dist/PageLayout.d.ts +2 -0
- package/dist/PageLayout.d.ts.map +1 -0
- package/dist/PageLayout.js +31 -0
- package/dist/PageLayout.js.map +1 -0
- package/dist/PageLayout.jsx +23 -0
- package/dist/PageLayout.jsx.map +1 -0
- package/dist/Picker.d.ts +2 -0
- package/dist/Picker.d.ts.map +1 -0
- package/dist/Picker.js +1 -0
- package/dist/Picker.jsx +1 -0
- package/dist/ProfileCard.d.ts +2 -0
- package/dist/ProfileCard.d.ts.map +1 -0
- package/dist/ProfileCard.js +78 -0
- package/dist/ProfileCard.js.map +1 -0
- package/dist/ProfileCard.jsx +53 -0
- package/dist/ProfileCard.jsx.map +1 -0
- package/dist/ProjectCard.d.ts +2 -0
- package/dist/ProjectCard.d.ts.map +1 -0
- package/dist/ProjectCard.js +164 -0
- package/dist/ProjectCard.js.map +1 -0
- package/dist/ProjectCard.jsx +133 -0
- package/dist/ProjectCard.jsx.map +1 -0
- package/dist/Provider.d.ts +2 -0
- package/dist/Provider.d.ts.map +1 -0
- package/dist/Provider.js +1 -0
- package/dist/Provider.jsx +1 -0
- package/dist/RangeCalendar.d.ts +2 -0
- package/dist/RangeCalendar.d.ts.map +1 -0
- package/dist/RangeCalendar.js +1 -0
- package/dist/RangeCalendar.jsx +1 -0
- package/dist/SearchField.d.ts +2 -0
- package/dist/SearchField.d.ts.map +1 -0
- package/dist/SearchField.js +1 -0
- package/dist/SearchField.jsx +1 -0
- package/dist/SegmentedControl.d.ts +2 -0
- package/dist/SegmentedControl.d.ts.map +1 -0
- package/dist/SegmentedControl.js +1 -0
- package/dist/SegmentedControl.jsx +1 -0
- package/dist/Switch.d.ts +2 -0
- package/dist/Switch.d.ts.map +1 -0
- package/dist/Switch.js +1 -0
- package/dist/Switch.jsx +1 -0
- package/dist/Tabs.d.ts +2 -0
- package/dist/Tabs.d.ts.map +1 -0
- package/dist/Tabs.js +1 -0
- package/dist/Tabs.jsx +1 -0
- package/dist/TextArea.d.ts +2 -0
- package/dist/TextArea.d.ts.map +1 -0
- package/dist/TextArea.js +1 -0
- package/dist/TextArea.jsx +1 -0
- package/dist/TextField.d.ts +2 -0
- package/dist/TextField.d.ts.map +1 -0
- package/dist/TextField.js +1 -0
- package/dist/TextField.jsx +1 -0
- package/dist/TimelineItem.d.ts +2 -0
- package/dist/TimelineItem.d.ts.map +1 -0
- package/dist/TimelineItem.js +137 -0
- package/dist/TimelineItem.js.map +1 -0
- package/dist/TimelineItem.jsx +70 -0
- package/dist/TimelineItem.jsx.map +1 -0
- package/dist/TreeView.d.ts +2 -0
- package/dist/TreeView.d.ts.map +1 -0
- package/dist/TreeView.js +1 -0
- package/dist/TreeView.jsx +1 -0
- package/dist/chip2.js +82 -0
- package/dist/chip2.js.map +1 -0
- package/dist/chip2.jsx +68 -0
- package/dist/chip2.jsx.map +1 -0
- package/dist/components.css +2 -1077
- package/dist/custom/calendar-card/index.d.ts.map +1 -1
- package/dist/custom/chip/index.d.ts +2 -2
- package/dist/custom/chip/index.d.ts.map +1 -1
- package/dist/custom/conversation/index.d.ts +2 -2
- package/dist/custom/conversation/index.d.ts.map +1 -1
- package/dist/custom/event-card/index.d.ts +1 -1
- package/dist/custom/event-card/index.d.ts.map +1 -1
- package/dist/custom/header/index.d.ts +2 -6
- package/dist/custom/header/index.d.ts.map +1 -1
- package/dist/custom/lateral-nav/index.d.ts +1 -1
- package/dist/custom/lateral-nav/index.d.ts.map +1 -1
- package/dist/custom/logo/index.d.ts +1 -18
- package/dist/custom/logo/index.d.ts.map +1 -1
- package/dist/custom/nav-header/index.d.ts +2 -1
- package/dist/custom/nav-header/index.d.ts.map +1 -1
- package/dist/custom/page-layout/index.d.ts +1 -7
- package/dist/custom/page-layout/index.d.ts.map +1 -1
- package/dist/custom/profile-card/index.d.ts +1 -1
- package/dist/custom/profile-card/index.d.ts.map +1 -1
- package/dist/custom/project-card/index.d.ts +2 -13
- package/dist/custom/project-card/index.d.ts.map +1 -1
- package/dist/custom/timeline-item/index.d.ts +2 -2
- package/dist/custom/timeline-item/index.d.ts.map +1 -1
- package/dist/font-faces.css +1 -0
- package/dist/index.d.ts +1 -104
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -8222
- package/dist/index.jsx +1 -0
- package/dist/style/runtime.d.ts +2 -0
- package/dist/style/runtime.d.ts.map +1 -0
- package/dist/style/runtime.js +1 -0
- package/dist/style/runtime.jsx +1 -0
- package/dist/style.d.ts +2 -0
- package/dist/style.d.ts.map +1 -0
- package/dist/style.js +1 -0
- package/dist/style.jsx +1 -0
- package/dist/styles.css +9 -450
- package/dist/theme.css +2 -101
- package/dist/vite.d.ts +15 -0
- package/dist/vite.d.ts.map +1 -0
- package/dist/vite.js +74 -0
- package/dist/vite.js.map +1 -0
- package/dist/vite.jsx +74 -0
- package/dist/vite.jsx.map +1 -0
- package/dist/viviana-tokens.css +318 -0
- package/package.json +300 -44
- package/src/ActionButton.ts +1 -0
- package/src/ActionMenu.ts +1 -0
- package/src/Breadcrumbs.ts +1 -0
- package/src/Button.ts +1 -0
- package/src/Calendar.ts +1 -0
- package/src/CalendarCard.ts +1 -0
- package/src/Card.ts +1 -0
- package/src/CardView.ts +1 -0
- package/src/CenterBaseline.ts +1 -0
- package/src/Chip.ts +1 -0
- package/src/ColorArea.ts +1 -0
- package/src/ColorField.ts +1 -0
- package/src/ColorSlider.ts +1 -0
- package/src/ColorSwatch.ts +1 -0
- package/src/ColorSwatchPicker.ts +1 -0
- package/src/ColorWheel.ts +1 -0
- package/src/ContrastIcon.ts +2 -0
- package/src/Conversation.ts +1 -0
- package/src/Disclosure.ts +1 -0
- package/src/EventCard.ts +1 -0
- package/src/FileTrigger.ts +1 -0
- package/src/GitHubIcon.ts +1 -0
- package/src/LightenIcon.ts +2 -0
- package/src/LinkButton.ts +1 -0
- package/src/ListView.ts +1 -0
- package/src/Logo.ts +1 -0
- package/src/Menu.ts +1 -0
- package/src/PageLayout.ts +1 -0
- package/src/Picker.ts +1 -0
- package/src/ProfileCard.ts +1 -0
- package/src/ProjectCard.ts +1 -0
- package/src/Provider.ts +1 -0
- package/src/RangeCalendar.ts +1 -0
- package/src/SearchField.ts +1 -0
- package/src/SegmentedControl.ts +1 -0
- package/src/Switch.ts +1 -0
- package/src/Tabs.ts +1 -0
- package/src/TextArea.ts +1 -0
- package/src/TextField.ts +1 -0
- package/src/TimelineItem.ts +1 -0
- package/src/TreeView.ts +1 -0
- package/src/components.css +2 -1077
- package/src/custom/calendar-card/index.tsx +99 -50
- package/src/custom/chip/index.tsx +59 -27
- package/src/custom/conversation/index.tsx +149 -55
- package/src/custom/event-card/index.tsx +174 -74
- package/src/custom/header/index.tsx +64 -33
- package/src/custom/lateral-nav/index.tsx +84 -38
- package/src/custom/logo/index.tsx +34 -39
- package/src/custom/nav-header/index.tsx +81 -25
- package/src/custom/page-layout/index.tsx +23 -19
- package/src/custom/profile-card/index.tsx +85 -35
- package/src/custom/project-card/index.tsx +57 -40
- package/src/custom/timeline-item/index.tsx +83 -48
- package/src/font-faces.css +1 -0
- package/src/index.ts +8 -322
- package/src/style/runtime.ts +2 -0
- package/src/style.ts +5 -0
- package/src/styles.css +6 -450
- package/src/theme.css +2 -101
- package/src/vite.ts +152 -0
- package/src/viviana-tokens.css +318 -0
- package/dist/alert/index.d.ts +0 -12
- package/dist/alert/index.d.ts.map +0 -1
- package/dist/autocomplete/index.d.ts +0 -89
- package/dist/autocomplete/index.d.ts.map +0 -1
- package/dist/avatar/index.d.ts +0 -17
- package/dist/avatar/index.d.ts.map +0 -1
- package/dist/badge/index.d.ts +0 -12
- package/dist/badge/index.d.ts.map +0 -1
- package/dist/breadcrumbs/index.d.ts +0 -38
- package/dist/breadcrumbs/index.d.ts.map +0 -1
- package/dist/button/Button.d.ts +0 -19
- package/dist/button/Button.d.ts.map +0 -1
- package/dist/button/index.d.ts +0 -3
- package/dist/button/index.d.ts.map +0 -1
- package/dist/button/types.d.ts +0 -23
- package/dist/button/types.d.ts.map +0 -1
- package/dist/calendar/DateField.d.ts +0 -47
- package/dist/calendar/DateField.d.ts.map +0 -1
- package/dist/calendar/DatePicker.d.ts +0 -48
- package/dist/calendar/DatePicker.d.ts.map +0 -1
- package/dist/calendar/RangeCalendar.d.ts +0 -42
- package/dist/calendar/RangeCalendar.d.ts.map +0 -1
- package/dist/calendar/TimeField.d.ts +0 -44
- package/dist/calendar/TimeField.d.ts.map +0 -1
- package/dist/calendar/index.d.ts +0 -50
- package/dist/calendar/index.d.ts.map +0 -1
- package/dist/checkbox/index.d.ts +0 -43
- package/dist/checkbox/index.d.ts.map +0 -1
- package/dist/color/index.d.ts +0 -228
- package/dist/color/index.d.ts.map +0 -1
- package/dist/combobox/index.d.ts +0 -81
- package/dist/combobox/index.d.ts.map +0 -1
- package/dist/dialog/Dialog.d.ts +0 -67
- package/dist/dialog/Dialog.d.ts.map +0 -1
- package/dist/dialog/index.d.ts +0 -3
- package/dist/dialog/index.d.ts.map +0 -1
- package/dist/disclosure/index.d.ts +0 -84
- package/dist/disclosure/index.d.ts.map +0 -1
- package/dist/gridlist/index.d.ts +0 -92
- package/dist/gridlist/index.d.ts.map +0 -1
- package/dist/icon/icons/GitHubIcon.d.ts +0 -7
- package/dist/icon/icons/GitHubIcon.d.ts.map +0 -1
- package/dist/icon/index.d.ts +0 -28
- package/dist/icon/index.d.ts.map +0 -1
- package/dist/index.js.map +0 -7
- package/dist/index.ssr.js +0 -6631
- package/dist/index.ssr.js.map +0 -7
- package/dist/landmark/index.d.ts +0 -83
- package/dist/landmark/index.d.ts.map +0 -1
- package/dist/link/index.d.ts +0 -39
- package/dist/link/index.d.ts.map +0 -1
- package/dist/listbox/index.d.ts +0 -47
- package/dist/listbox/index.d.ts.map +0 -1
- package/dist/menu/index.d.ts +0 -74
- package/dist/menu/index.d.ts.map +0 -1
- package/dist/meter/index.d.ts +0 -49
- package/dist/meter/index.d.ts.map +0 -1
- package/dist/numberfield/index.d.ts +0 -50
- package/dist/numberfield/index.d.ts.map +0 -1
- package/dist/popover/index.d.ts +0 -85
- package/dist/popover/index.d.ts.map +0 -1
- package/dist/progress-bar/index.d.ts +0 -49
- package/dist/progress-bar/index.d.ts.map +0 -1
- package/dist/radio/index.d.ts +0 -46
- package/dist/radio/index.d.ts.map +0 -1
- package/dist/searchfield/index.d.ts +0 -44
- package/dist/searchfield/index.d.ts.map +0 -1
- package/dist/select/index.d.ts +0 -72
- package/dist/select/index.d.ts.map +0 -1
- package/dist/separator/index.d.ts +0 -42
- package/dist/separator/index.d.ts.map +0 -1
- package/dist/slider/index.d.ts +0 -53
- package/dist/slider/index.d.ts.map +0 -1
- package/dist/switch/ToggleSwitch.d.ts +0 -28
- package/dist/switch/ToggleSwitch.d.ts.map +0 -1
- package/dist/switch/index.d.ts +0 -26
- package/dist/switch/index.d.ts.map +0 -1
- package/dist/table/index.d.ts +0 -140
- package/dist/table/index.d.ts.map +0 -1
- package/dist/tabs/index.d.ts +0 -56
- package/dist/tabs/index.d.ts.map +0 -1
- package/dist/tag-group/index.d.ts +0 -80
- package/dist/tag-group/index.d.ts.map +0 -1
- package/dist/test-utils/index.d.ts +0 -44
- package/dist/test-utils/index.d.ts.map +0 -1
- package/dist/textfield/index.d.ts +0 -31
- package/dist/textfield/index.d.ts.map +0 -1
- package/dist/toast/index.d.ts +0 -101
- package/dist/toast/index.d.ts.map +0 -1
- package/dist/toolbar/index.d.ts +0 -42
- package/dist/toolbar/index.d.ts.map +0 -1
- package/dist/tooltip/index.d.ts +0 -78
- package/dist/tooltip/index.d.ts.map +0 -1
- package/dist/tree/index.d.ts +0 -99
- package/dist/tree/index.d.ts.map +0 -1
- package/src/alert/index.tsx +0 -48
- package/src/assets/favicon.png +0 -0
- package/src/assets/fire.gif +0 -0
- package/src/autocomplete/index.tsx +0 -313
- package/src/avatar/index.tsx +0 -75
- package/src/badge/index.tsx +0 -43
- package/src/breadcrumbs/index.tsx +0 -207
- package/src/button/Button.tsx +0 -74
- package/src/button/index.ts +0 -2
- package/src/button/types.ts +0 -24
- package/src/calendar/DateField.tsx +0 -200
- package/src/calendar/DatePicker.tsx +0 -298
- package/src/calendar/RangeCalendar.tsx +0 -236
- package/src/calendar/TimeField.tsx +0 -196
- package/src/calendar/index.tsx +0 -223
- package/src/checkbox/index.tsx +0 -257
- package/src/color/index.tsx +0 -687
- package/src/combobox/index.tsx +0 -383
- package/src/dialog/Dialog.tsx +0 -260
- package/src/dialog/index.tsx +0 -3
- package/src/disclosure/index.tsx +0 -307
- package/src/gridlist/index.tsx +0 -403
- package/src/icon/icons/GitHubIcon.tsx +0 -20
- package/src/icon/index.tsx +0 -48
- package/src/landmark/index.tsx +0 -231
- package/src/link/index.tsx +0 -130
- package/src/listbox/index.tsx +0 -231
- package/src/menu/index.tsx +0 -297
- package/src/meter/index.tsx +0 -163
- package/src/numberfield/index.tsx +0 -482
- package/src/popover/index.tsx +0 -260
- package/src/progress-bar/index.tsx +0 -169
- package/src/radio/index.tsx +0 -173
- package/src/searchfield/index.tsx +0 -453
- package/src/select/index.tsx +0 -349
- package/src/separator/index.tsx +0 -141
- package/src/slider/index.tsx +0 -382
- package/src/switch/ToggleSwitch.tsx +0 -112
- package/src/switch/index.tsx +0 -90
- package/src/table/index.tsx +0 -531
- package/src/tabs/index.tsx +0 -273
- package/src/tag-group/index.tsx +0 -240
- package/src/test-utils/index.ts +0 -40
- package/src/textfield/index.tsx +0 -211
- package/src/toast/index.tsx +0 -324
- package/src/toolbar/index.tsx +0 -108
- package/src/tooltip/index.tsx +0 -197
- package/src/tree/index.tsx +0 -494
|
@@ -1,313 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* SearchAutocomplete component for proyecto-viviana-ui
|
|
3
|
-
*
|
|
4
|
-
* A styled autocomplete component combining a search input with a
|
|
5
|
-
* filterable dropdown list of options.
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
import { type JSX, splitProps, createMemo, Show, For, createSignal } from 'solid-js'
|
|
9
|
-
import {
|
|
10
|
-
Autocomplete,
|
|
11
|
-
useAutocompleteInput,
|
|
12
|
-
useAutocompleteCollection,
|
|
13
|
-
useAutocompleteState,
|
|
14
|
-
} from '@proyecto-viviana/solidaria-components'
|
|
15
|
-
|
|
16
|
-
// ============================================
|
|
17
|
-
// TYPES
|
|
18
|
-
// ============================================
|
|
19
|
-
|
|
20
|
-
export type SearchAutocompleteSize = 'sm' | 'md' | 'lg'
|
|
21
|
-
|
|
22
|
-
export interface SearchAutocompleteItem {
|
|
23
|
-
id: string
|
|
24
|
-
name: string
|
|
25
|
-
[key: string]: unknown
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
export interface SearchAutocompleteProps<T extends SearchAutocompleteItem = SearchAutocompleteItem> {
|
|
29
|
-
/** The items to display in the dropdown. */
|
|
30
|
-
items: T[]
|
|
31
|
-
/** The size of the autocomplete. @default 'md' */
|
|
32
|
-
size?: SearchAutocompleteSize
|
|
33
|
-
/** Placeholder text for the input. */
|
|
34
|
-
placeholder?: string
|
|
35
|
-
/** Accessible label for the input. */
|
|
36
|
-
'aria-label'?: string
|
|
37
|
-
/** Label text shown above the input. */
|
|
38
|
-
label?: string
|
|
39
|
-
/** Description text shown below the input. */
|
|
40
|
-
description?: string
|
|
41
|
-
/** The current input value (controlled). */
|
|
42
|
-
inputValue?: string
|
|
43
|
-
/** The default input value (uncontrolled). */
|
|
44
|
-
defaultInputValue?: string
|
|
45
|
-
/** Handler called when the input value changes. */
|
|
46
|
-
onInputChange?: (value: string) => void
|
|
47
|
-
/** Handler called when an item is selected. */
|
|
48
|
-
onSelect?: (item: T) => void
|
|
49
|
-
/** Additional CSS class name. */
|
|
50
|
-
class?: string
|
|
51
|
-
/** Whether the input is disabled. */
|
|
52
|
-
isDisabled?: boolean
|
|
53
|
-
/**
|
|
54
|
-
* Custom filter function. By default, filters by case-insensitive name match.
|
|
55
|
-
*/
|
|
56
|
-
filter?: (textValue: string, inputValue: string) => boolean
|
|
57
|
-
/**
|
|
58
|
-
* Custom render function for items.
|
|
59
|
-
*/
|
|
60
|
-
renderItem?: (item: T) => JSX.Element
|
|
61
|
-
/**
|
|
62
|
-
* Key to use for the display text. @default 'name'
|
|
63
|
-
*/
|
|
64
|
-
textKey?: keyof T
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
// ============================================
|
|
68
|
-
// STYLES
|
|
69
|
-
// ============================================
|
|
70
|
-
|
|
71
|
-
const sizeStyles = {
|
|
72
|
-
sm: {
|
|
73
|
-
container: 'text-sm',
|
|
74
|
-
input: 'h-8 px-3 text-sm',
|
|
75
|
-
label: 'text-xs mb-1',
|
|
76
|
-
list: 'max-h-48',
|
|
77
|
-
item: 'px-3 py-1.5 text-sm',
|
|
78
|
-
},
|
|
79
|
-
md: {
|
|
80
|
-
container: 'text-base',
|
|
81
|
-
input: 'h-10 px-4 text-base',
|
|
82
|
-
label: 'text-sm mb-1.5',
|
|
83
|
-
list: 'max-h-64',
|
|
84
|
-
item: 'px-4 py-2 text-base',
|
|
85
|
-
},
|
|
86
|
-
lg: {
|
|
87
|
-
container: 'text-lg',
|
|
88
|
-
input: 'h-12 px-5 text-lg',
|
|
89
|
-
label: 'text-base mb-2',
|
|
90
|
-
list: 'max-h-80',
|
|
91
|
-
item: 'px-5 py-2.5 text-lg',
|
|
92
|
-
},
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
// ============================================
|
|
96
|
-
// INNER COMPONENTS
|
|
97
|
-
// ============================================
|
|
98
|
-
|
|
99
|
-
function AutocompleteInput(props: {
|
|
100
|
-
placeholder?: string
|
|
101
|
-
'aria-label'?: string
|
|
102
|
-
isDisabled?: boolean
|
|
103
|
-
size: SearchAutocompleteSize
|
|
104
|
-
}) {
|
|
105
|
-
const ctx = useAutocompleteInput()
|
|
106
|
-
if (!ctx) return null
|
|
107
|
-
|
|
108
|
-
const styles = () => sizeStyles[props.size]
|
|
109
|
-
|
|
110
|
-
return (
|
|
111
|
-
<input
|
|
112
|
-
ref={ctx.inputRef}
|
|
113
|
-
type="text"
|
|
114
|
-
placeholder={props.placeholder}
|
|
115
|
-
aria-label={props['aria-label']}
|
|
116
|
-
disabled={props.isDisabled}
|
|
117
|
-
value={ctx.inputProps.value()}
|
|
118
|
-
onInput={(e) => ctx.inputProps.onChange(e.currentTarget.value)}
|
|
119
|
-
onKeyDown={ctx.inputProps.onKeyDown}
|
|
120
|
-
onFocus={ctx.inputProps.onFocus}
|
|
121
|
-
onBlur={ctx.inputProps.onBlur}
|
|
122
|
-
aria-activedescendant={ctx.inputProps['aria-activedescendant']()}
|
|
123
|
-
aria-controls={ctx.inputProps['aria-controls']}
|
|
124
|
-
aria-autocomplete={ctx.inputProps['aria-autocomplete']}
|
|
125
|
-
autocomplete={ctx.inputProps.autoComplete}
|
|
126
|
-
autocorrect={ctx.inputProps.autoCorrect}
|
|
127
|
-
spellcheck={ctx.inputProps.spellCheck !== 'false'}
|
|
128
|
-
class={[
|
|
129
|
-
'w-full rounded-md border border-bg-200 bg-bg-50',
|
|
130
|
-
'focus:outline-none focus:ring-2 focus:ring-primary-500 focus:border-primary-500',
|
|
131
|
-
'placeholder:text-text-400',
|
|
132
|
-
'disabled:opacity-50 disabled:cursor-not-allowed',
|
|
133
|
-
styles().input,
|
|
134
|
-
].join(' ')}
|
|
135
|
-
/>
|
|
136
|
-
)
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
function AutocompleteList<T extends SearchAutocompleteItem>(props: {
|
|
140
|
-
items: T[]
|
|
141
|
-
size: SearchAutocompleteSize
|
|
142
|
-
onSelect?: (item: T) => void
|
|
143
|
-
renderItem?: (item: T) => JSX.Element
|
|
144
|
-
textKey: keyof T
|
|
145
|
-
}) {
|
|
146
|
-
const ctx = useAutocompleteCollection()
|
|
147
|
-
const state = useAutocompleteState()
|
|
148
|
-
if (!ctx) return null
|
|
149
|
-
|
|
150
|
-
const styles = () => sizeStyles[props.size]
|
|
151
|
-
|
|
152
|
-
// Filter items based on input
|
|
153
|
-
const filteredItems = createMemo(() => {
|
|
154
|
-
if (!ctx.filter) return props.items
|
|
155
|
-
return props.items.filter((item) => {
|
|
156
|
-
const textValue = String(item[props.textKey] ?? item.name ?? '')
|
|
157
|
-
return ctx.filter!(textValue)
|
|
158
|
-
})
|
|
159
|
-
})
|
|
160
|
-
|
|
161
|
-
const handleSelect = (item: T) => {
|
|
162
|
-
props.onSelect?.(item)
|
|
163
|
-
state?.setInputValue(String(item[props.textKey] ?? item.name ?? ''))
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
return (
|
|
167
|
-
<Show when={filteredItems().length > 0}>
|
|
168
|
-
<ul
|
|
169
|
-
ref={ctx.collectionRef}
|
|
170
|
-
id={ctx.collectionProps.id}
|
|
171
|
-
role="listbox"
|
|
172
|
-
aria-label={ctx.collectionProps['aria-label']}
|
|
173
|
-
class={[
|
|
174
|
-
'mt-1 w-full rounded-md border border-bg-200 bg-bg-50 shadow-lg',
|
|
175
|
-
'overflow-auto',
|
|
176
|
-
styles().list,
|
|
177
|
-
].join(' ')}
|
|
178
|
-
>
|
|
179
|
-
<For each={filteredItems()}>
|
|
180
|
-
{(item) => {
|
|
181
|
-
const itemId = `autocomplete-item-${item.id}`
|
|
182
|
-
const isFocused = () => state?.focusedNodeId() === itemId
|
|
183
|
-
|
|
184
|
-
return (
|
|
185
|
-
<li
|
|
186
|
-
id={itemId}
|
|
187
|
-
role="option"
|
|
188
|
-
aria-selected={isFocused()}
|
|
189
|
-
onClick={() => handleSelect(item)}
|
|
190
|
-
onMouseEnter={() => state?.setFocusedNodeId(itemId)}
|
|
191
|
-
onMouseLeave={() => {
|
|
192
|
-
if (state?.focusedNodeId() === itemId) {
|
|
193
|
-
state?.setFocusedNodeId(null)
|
|
194
|
-
}
|
|
195
|
-
}}
|
|
196
|
-
class={[
|
|
197
|
-
'cursor-pointer transition-colors',
|
|
198
|
-
isFocused()
|
|
199
|
-
? 'bg-primary-100 text-primary-900'
|
|
200
|
-
: 'hover:bg-bg-100',
|
|
201
|
-
styles().item,
|
|
202
|
-
].join(' ')}
|
|
203
|
-
>
|
|
204
|
-
{props.renderItem ? props.renderItem(item) : String(item[props.textKey] ?? item.name)}
|
|
205
|
-
</li>
|
|
206
|
-
)
|
|
207
|
-
}}
|
|
208
|
-
</For>
|
|
209
|
-
</ul>
|
|
210
|
-
</Show>
|
|
211
|
-
)
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
// ============================================
|
|
215
|
-
// SEARCH AUTOCOMPLETE COMPONENT
|
|
216
|
-
// ============================================
|
|
217
|
-
|
|
218
|
-
/**
|
|
219
|
-
* A styled autocomplete component for searching and selecting from a list.
|
|
220
|
-
*
|
|
221
|
-
* @example
|
|
222
|
-
* ```tsx
|
|
223
|
-
* const items = [
|
|
224
|
-
* { id: '1', name: 'Apple' },
|
|
225
|
-
* { id: '2', name: 'Banana' },
|
|
226
|
-
* { id: '3', name: 'Cherry' },
|
|
227
|
-
* ];
|
|
228
|
-
*
|
|
229
|
-
* <SearchAutocomplete
|
|
230
|
-
* items={items}
|
|
231
|
-
* placeholder="Search fruits..."
|
|
232
|
-
* aria-label="Fruit search"
|
|
233
|
-
* onSelect={(item) => console.log('Selected:', item)}
|
|
234
|
-
* />
|
|
235
|
-
*
|
|
236
|
-
* // With custom filter
|
|
237
|
-
* <SearchAutocomplete
|
|
238
|
-
* items={items}
|
|
239
|
-
* filter={(textValue, inputValue) =>
|
|
240
|
-
* textValue.toLowerCase().startsWith(inputValue.toLowerCase())
|
|
241
|
-
* }
|
|
242
|
-
* onSelect={(item) => console.log('Selected:', item)}
|
|
243
|
-
* />
|
|
244
|
-
*
|
|
245
|
-
* // With label and description
|
|
246
|
-
* <SearchAutocomplete
|
|
247
|
-
* items={items}
|
|
248
|
-
* label="Search"
|
|
249
|
-
* description="Type to filter the list"
|
|
250
|
-
* placeholder="Start typing..."
|
|
251
|
-
* />
|
|
252
|
-
* ```
|
|
253
|
-
*/
|
|
254
|
-
export function SearchAutocomplete<T extends SearchAutocompleteItem = SearchAutocompleteItem>(
|
|
255
|
-
props: SearchAutocompleteProps<T>
|
|
256
|
-
): JSX.Element {
|
|
257
|
-
const [local, autocompleteProps] = splitProps(props, [
|
|
258
|
-
'items',
|
|
259
|
-
'size',
|
|
260
|
-
'placeholder',
|
|
261
|
-
'aria-label',
|
|
262
|
-
'label',
|
|
263
|
-
'description',
|
|
264
|
-
'onSelect',
|
|
265
|
-
'class',
|
|
266
|
-
'isDisabled',
|
|
267
|
-
'renderItem',
|
|
268
|
-
'textKey',
|
|
269
|
-
])
|
|
270
|
-
|
|
271
|
-
const size = () => local.size ?? 'md'
|
|
272
|
-
const textKey = () => local.textKey ?? 'name'
|
|
273
|
-
const styles = () => sizeStyles[size()]
|
|
274
|
-
|
|
275
|
-
// Default filter: case-insensitive contains
|
|
276
|
-
const defaultFilter = (textValue: string, inputValue: string) => {
|
|
277
|
-
if (!inputValue) return true
|
|
278
|
-
return textValue.toLowerCase().includes(inputValue.toLowerCase())
|
|
279
|
-
}
|
|
280
|
-
|
|
281
|
-
return (
|
|
282
|
-
<div class={['vui-search-autocomplete relative', styles().container, local.class].filter(Boolean).join(' ')}>
|
|
283
|
-
<Show when={local.label}>
|
|
284
|
-
<label class={['block font-medium text-text-700', styles().label].join(' ')}>
|
|
285
|
-
{local.label}
|
|
286
|
-
</label>
|
|
287
|
-
</Show>
|
|
288
|
-
|
|
289
|
-
<Autocomplete
|
|
290
|
-
{...autocompleteProps}
|
|
291
|
-
filter={autocompleteProps.filter ?? defaultFilter}
|
|
292
|
-
>
|
|
293
|
-
<AutocompleteInput
|
|
294
|
-
placeholder={local.placeholder}
|
|
295
|
-
aria-label={local['aria-label']}
|
|
296
|
-
isDisabled={local.isDisabled}
|
|
297
|
-
size={size()}
|
|
298
|
-
/>
|
|
299
|
-
<AutocompleteList
|
|
300
|
-
items={local.items}
|
|
301
|
-
size={size()}
|
|
302
|
-
onSelect={local.onSelect}
|
|
303
|
-
renderItem={local.renderItem}
|
|
304
|
-
textKey={textKey() as keyof T}
|
|
305
|
-
/>
|
|
306
|
-
</Autocomplete>
|
|
307
|
-
|
|
308
|
-
<Show when={local.description}>
|
|
309
|
-
<p class="mt-1 text-sm text-text-500">{local.description}</p>
|
|
310
|
-
</Show>
|
|
311
|
-
</div>
|
|
312
|
-
)
|
|
313
|
-
}
|
package/src/avatar/index.tsx
DELETED
|
@@ -1,75 +0,0 @@
|
|
|
1
|
-
import { Show } from 'solid-js'
|
|
2
|
-
|
|
3
|
-
export type AvatarSize = 'xs' | 'sm' | 'md' | 'lg' | 'xl'
|
|
4
|
-
|
|
5
|
-
export interface AvatarProps {
|
|
6
|
-
src?: string
|
|
7
|
-
alt?: string
|
|
8
|
-
size?: AvatarSize
|
|
9
|
-
fallback?: string
|
|
10
|
-
online?: boolean
|
|
11
|
-
class?: string
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
const sizeStyles: Record<AvatarSize, { container: string; text: string; indicator: string }> = {
|
|
15
|
-
xs: { container: 'w-6 h-6', text: 'text-xs', indicator: 'w-1.5 h-1.5' },
|
|
16
|
-
sm: { container: 'w-8 h-8', text: 'text-sm', indicator: 'w-2 h-2' },
|
|
17
|
-
md: { container: 'w-10 h-10', text: 'text-base', indicator: 'w-2.5 h-2.5' },
|
|
18
|
-
lg: { container: 'w-14 h-14', text: 'text-lg', indicator: 'w-3 h-3' },
|
|
19
|
-
xl: { container: 'w-20 h-20', text: 'text-xl', indicator: 'w-4 h-4' },
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
export function Avatar(props: AvatarProps) {
|
|
23
|
-
const size = () => props.size ?? 'md'
|
|
24
|
-
const styles = () => sizeStyles[size()]
|
|
25
|
-
|
|
26
|
-
const initials = () => {
|
|
27
|
-
if (props.fallback) return props.fallback.slice(0, 2).toUpperCase()
|
|
28
|
-
if (props.alt) return props.alt.slice(0, 2).toUpperCase()
|
|
29
|
-
return '?'
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
return (
|
|
33
|
-
<div class={`relative inline-block ${props.class ?? ''}`}>
|
|
34
|
-
<div
|
|
35
|
-
class={`${styles().container} rounded-full overflow-hidden bg-bg-200 flex items-center justify-center ring-2 ring-accent/50`}
|
|
36
|
-
>
|
|
37
|
-
<Show
|
|
38
|
-
when={props.src}
|
|
39
|
-
fallback={
|
|
40
|
-
<span class={`${styles().text} font-medium text-primary-300`}>
|
|
41
|
-
{initials()}
|
|
42
|
-
</span>
|
|
43
|
-
}
|
|
44
|
-
>
|
|
45
|
-
<img
|
|
46
|
-
src={props.src}
|
|
47
|
-
alt={props.alt ?? 'Avatar'}
|
|
48
|
-
class="w-full h-full object-cover"
|
|
49
|
-
/>
|
|
50
|
-
</Show>
|
|
51
|
-
</div>
|
|
52
|
-
<Show when={props.online !== undefined}>
|
|
53
|
-
<span
|
|
54
|
-
class={`absolute bottom-0 right-0 ${styles().indicator} rounded-full ring-2 ring-bg-400 ${
|
|
55
|
-
props.online ? 'bg-success-400' : 'bg-bg-light'
|
|
56
|
-
}`}
|
|
57
|
-
/>
|
|
58
|
-
</Show>
|
|
59
|
-
</div>
|
|
60
|
-
)
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
export interface AvatarGroupProps {
|
|
64
|
-
children: any
|
|
65
|
-
max?: number
|
|
66
|
-
size?: AvatarSize
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
export function AvatarGroup(props: AvatarGroupProps) {
|
|
70
|
-
return (
|
|
71
|
-
<div class="flex -space-x-2">
|
|
72
|
-
{props.children}
|
|
73
|
-
</div>
|
|
74
|
-
)
|
|
75
|
-
}
|
package/src/badge/index.tsx
DELETED
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
import type { JSX } from 'solid-js'
|
|
2
|
-
import { Show } from 'solid-js'
|
|
3
|
-
|
|
4
|
-
export type BadgeVariant = 'primary' | 'secondary' | 'accent' | 'success' | 'warning' | 'danger'
|
|
5
|
-
export type BadgeSize = 'sm' | 'md' | 'lg'
|
|
6
|
-
|
|
7
|
-
export interface BadgeProps {
|
|
8
|
-
children?: JSX.Element
|
|
9
|
-
count?: number
|
|
10
|
-
variant?: BadgeVariant
|
|
11
|
-
size?: BadgeSize
|
|
12
|
-
class?: string
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
const variantStyles: Record<BadgeVariant, string> = {
|
|
16
|
-
primary: 'bg-primary-500 text-white',
|
|
17
|
-
secondary: 'bg-bg-300 text-primary-300',
|
|
18
|
-
accent: 'bg-accent-300 text-black',
|
|
19
|
-
success: 'bg-success-400 text-white',
|
|
20
|
-
warning: 'bg-warning-400 text-black',
|
|
21
|
-
danger: 'bg-danger-400 text-white',
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
const sizeStyles: Record<BadgeSize, string> = {
|
|
25
|
-
sm: 'w-5 h-5 text-xs',
|
|
26
|
-
md: 'w-7 h-7 text-xs',
|
|
27
|
-
lg: 'w-9 h-9 text-sm',
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
export function Badge(props: BadgeProps) {
|
|
31
|
-
const variant = () => props.variant ?? 'accent'
|
|
32
|
-
const size = () => props.size ?? 'md'
|
|
33
|
-
|
|
34
|
-
return (
|
|
35
|
-
<div
|
|
36
|
-
class={`flex items-center justify-center rounded-full border-b border-white font-semibold ${variantStyles[variant()]} ${sizeStyles[size()]} ${props.class ?? ''}`}
|
|
37
|
-
>
|
|
38
|
-
<Show when={props.count !== undefined} fallback={props.children}>
|
|
39
|
-
<span>{props.count}</span>
|
|
40
|
-
</Show>
|
|
41
|
-
</div>
|
|
42
|
-
)
|
|
43
|
-
}
|
|
@@ -1,207 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Breadcrumbs component for proyecto-viviana-ui
|
|
3
|
-
*
|
|
4
|
-
* Styled breadcrumbs component built on top of solidaria-components.
|
|
5
|
-
* Inspired by Spectrum 2's Breadcrumbs component patterns.
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
import { type JSX, splitProps, createContext, useContext } from 'solid-js'
|
|
9
|
-
import {
|
|
10
|
-
Breadcrumbs as HeadlessBreadcrumbs,
|
|
11
|
-
BreadcrumbItem as HeadlessBreadcrumbItem,
|
|
12
|
-
type BreadcrumbsProps as HeadlessBreadcrumbsProps,
|
|
13
|
-
type BreadcrumbItemProps as HeadlessBreadcrumbItemProps,
|
|
14
|
-
type BreadcrumbsRenderProps,
|
|
15
|
-
type BreadcrumbItemRenderProps,
|
|
16
|
-
} from '@proyecto-viviana/solidaria-components'
|
|
17
|
-
|
|
18
|
-
// ============================================
|
|
19
|
-
// SIZE CONTEXT
|
|
20
|
-
// ============================================
|
|
21
|
-
|
|
22
|
-
export type BreadcrumbsSize = 'sm' | 'md' | 'lg'
|
|
23
|
-
export type BreadcrumbsVariant = 'default' | 'subtle'
|
|
24
|
-
|
|
25
|
-
interface BreadcrumbsContextValue {
|
|
26
|
-
size: BreadcrumbsSize
|
|
27
|
-
variant: BreadcrumbsVariant
|
|
28
|
-
showSeparator: boolean
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
const BreadcrumbsSizeContext = createContext<BreadcrumbsContextValue>({
|
|
32
|
-
size: 'md',
|
|
33
|
-
variant: 'default',
|
|
34
|
-
showSeparator: true,
|
|
35
|
-
})
|
|
36
|
-
|
|
37
|
-
// ============================================
|
|
38
|
-
// TYPES
|
|
39
|
-
// ============================================
|
|
40
|
-
|
|
41
|
-
export interface BreadcrumbsProps<T> extends Omit<HeadlessBreadcrumbsProps<T>, 'class' | 'style'> {
|
|
42
|
-
/** The size of the breadcrumbs. */
|
|
43
|
-
size?: BreadcrumbsSize
|
|
44
|
-
/** The visual variant. */
|
|
45
|
-
variant?: BreadcrumbsVariant
|
|
46
|
-
/** Whether to show separators between items. */
|
|
47
|
-
showSeparator?: boolean
|
|
48
|
-
/** Additional CSS class name. */
|
|
49
|
-
class?: string
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
export interface BreadcrumbItemProps extends Omit<HeadlessBreadcrumbItemProps, 'class' | 'style'> {
|
|
53
|
-
/** Additional CSS class name. */
|
|
54
|
-
class?: string
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
// ============================================
|
|
58
|
-
// STYLES
|
|
59
|
-
// ============================================
|
|
60
|
-
|
|
61
|
-
const sizeStyles = {
|
|
62
|
-
sm: {
|
|
63
|
-
text: 'text-sm',
|
|
64
|
-
icon: 'h-3 w-3',
|
|
65
|
-
gap: 'gap-1',
|
|
66
|
-
},
|
|
67
|
-
md: {
|
|
68
|
-
text: 'text-base',
|
|
69
|
-
icon: 'h-4 w-4',
|
|
70
|
-
gap: 'gap-1.5',
|
|
71
|
-
},
|
|
72
|
-
lg: {
|
|
73
|
-
text: 'text-lg',
|
|
74
|
-
icon: 'h-5 w-5',
|
|
75
|
-
gap: 'gap-2',
|
|
76
|
-
},
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
const variantStyles = {
|
|
80
|
-
default: {
|
|
81
|
-
item: 'text-primary-400 hover:text-primary-200',
|
|
82
|
-
current: 'text-primary-100 font-medium',
|
|
83
|
-
separator: 'text-primary-500',
|
|
84
|
-
},
|
|
85
|
-
subtle: {
|
|
86
|
-
item: 'text-primary-500 hover:text-primary-300',
|
|
87
|
-
current: 'text-primary-200',
|
|
88
|
-
separator: 'text-primary-600',
|
|
89
|
-
},
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
// ============================================
|
|
93
|
-
// BREADCRUMBS COMPONENT
|
|
94
|
-
// ============================================
|
|
95
|
-
|
|
96
|
-
/**
|
|
97
|
-
* Breadcrumbs show hierarchy and navigational context for a user's location within an application.
|
|
98
|
-
*
|
|
99
|
-
* Built on solidaria-components Breadcrumbs for full accessibility support.
|
|
100
|
-
*/
|
|
101
|
-
export function Breadcrumbs<T>(props: BreadcrumbsProps<T>): JSX.Element {
|
|
102
|
-
const [local, headlessProps] = splitProps(props, [
|
|
103
|
-
'size',
|
|
104
|
-
'variant',
|
|
105
|
-
'showSeparator',
|
|
106
|
-
'class',
|
|
107
|
-
])
|
|
108
|
-
|
|
109
|
-
const size = local.size ?? 'md'
|
|
110
|
-
const variant = local.variant ?? 'default'
|
|
111
|
-
const showSeparator = local.showSeparator ?? true
|
|
112
|
-
const customClass = local.class ?? ''
|
|
113
|
-
|
|
114
|
-
const getClassName = (renderProps: BreadcrumbsRenderProps): string => {
|
|
115
|
-
const base = 'flex items-center'
|
|
116
|
-
const sizeClass = sizeStyles[size].gap
|
|
117
|
-
const disabledClass = renderProps.isDisabled ? 'opacity-50' : ''
|
|
118
|
-
return [base, sizeClass, disabledClass, customClass].filter(Boolean).join(' ')
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
return (
|
|
122
|
-
<BreadcrumbsSizeContext.Provider value={{ size, variant, showSeparator }}>
|
|
123
|
-
<HeadlessBreadcrumbs
|
|
124
|
-
{...headlessProps}
|
|
125
|
-
class={getClassName}
|
|
126
|
-
children={props.children}
|
|
127
|
-
/>
|
|
128
|
-
</BreadcrumbsSizeContext.Provider>
|
|
129
|
-
)
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
// ============================================
|
|
133
|
-
// BREADCRUMB ITEM COMPONENT
|
|
134
|
-
// ============================================
|
|
135
|
-
|
|
136
|
-
/**
|
|
137
|
-
* A BreadcrumbItem represents an individual breadcrumb in the navigation trail.
|
|
138
|
-
*/
|
|
139
|
-
export function BreadcrumbItem(props: BreadcrumbItemProps): JSX.Element {
|
|
140
|
-
const [local, headlessProps] = splitProps(props, ['class'])
|
|
141
|
-
const ctx = useContext(BreadcrumbsSizeContext)
|
|
142
|
-
const customClass = local.class ?? ''
|
|
143
|
-
|
|
144
|
-
const getClassName = (renderProps: BreadcrumbItemRenderProps): string => {
|
|
145
|
-
const sizeClass = sizeStyles[ctx.size].text
|
|
146
|
-
const vStyles = variantStyles[ctx.variant]
|
|
147
|
-
|
|
148
|
-
let stateClass: string
|
|
149
|
-
if (renderProps.isCurrent) {
|
|
150
|
-
stateClass = vStyles.current
|
|
151
|
-
} else if (renderProps.isDisabled) {
|
|
152
|
-
stateClass = 'text-primary-600 cursor-not-allowed'
|
|
153
|
-
} else {
|
|
154
|
-
stateClass = vStyles.item
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
const cursorClass = renderProps.isCurrent || renderProps.isDisabled ? '' : 'cursor-pointer'
|
|
158
|
-
const transitionClass = 'transition-colors duration-150'
|
|
159
|
-
const focusClass = renderProps.isFocusVisible
|
|
160
|
-
? 'ring-2 ring-accent-300 ring-offset-1 ring-offset-bg-400 outline-none rounded'
|
|
161
|
-
: ''
|
|
162
|
-
|
|
163
|
-
return [sizeClass, stateClass, cursorClass, transitionClass, focusClass, customClass].filter(Boolean).join(' ')
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
const vStyles = variantStyles[ctx.variant]
|
|
167
|
-
// Hide separator on first item, and on current (last) item
|
|
168
|
-
const separatorClass = `${sizeStyles[ctx.size].icon} ${vStyles.separator} mx-1 shrink-0 hidden data-current:hidden [&:not([data-current])]:block [li:first-child_&]:!hidden`
|
|
169
|
-
|
|
170
|
-
// Wrap children with separator icon
|
|
171
|
-
const renderChildren = () => (
|
|
172
|
-
<>
|
|
173
|
-
{/* Separator shows before items except first and current */}
|
|
174
|
-
{ctx.showSeparator && <ChevronIcon class={separatorClass} />}
|
|
175
|
-
{props.children as JSX.Element}
|
|
176
|
-
</>
|
|
177
|
-
)
|
|
178
|
-
|
|
179
|
-
return (
|
|
180
|
-
<HeadlessBreadcrumbItem
|
|
181
|
-
{...headlessProps}
|
|
182
|
-
class={getClassName}
|
|
183
|
-
children={renderChildren()}
|
|
184
|
-
/>
|
|
185
|
-
)
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
// ============================================
|
|
189
|
-
// ICONS
|
|
190
|
-
// ============================================
|
|
191
|
-
|
|
192
|
-
function ChevronIcon(props: { class?: string }): JSX.Element {
|
|
193
|
-
return (
|
|
194
|
-
<svg
|
|
195
|
-
class={props.class}
|
|
196
|
-
fill="none"
|
|
197
|
-
viewBox="0 0 24 24"
|
|
198
|
-
stroke="currentColor"
|
|
199
|
-
stroke-width="2"
|
|
200
|
-
>
|
|
201
|
-
<path stroke-linecap="round" stroke-linejoin="round" d="M9 5l7 7-7 7" />
|
|
202
|
-
</svg>
|
|
203
|
-
)
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
// Attach sub-components for convenience
|
|
207
|
-
Breadcrumbs.Item = BreadcrumbItem
|