@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
package/src/combobox/index.tsx
DELETED
|
@@ -1,383 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* ComboBox component for proyecto-viviana-ui
|
|
3
|
-
*
|
|
4
|
-
* Styled combobox component built on top of solidaria-components.
|
|
5
|
-
* Inspired by Spectrum 2's ComboBox component patterns.
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
import { type JSX, splitProps, createContext, useContext, Show } from 'solid-js'
|
|
9
|
-
import {
|
|
10
|
-
ComboBox as HeadlessComboBox,
|
|
11
|
-
ComboBoxInput as HeadlessComboBoxInput,
|
|
12
|
-
ComboBoxButton as HeadlessComboBoxButton,
|
|
13
|
-
ComboBoxListBox as HeadlessComboBoxListBox,
|
|
14
|
-
ComboBoxOption as HeadlessComboBoxOption,
|
|
15
|
-
defaultContainsFilter,
|
|
16
|
-
type ComboBoxProps as HeadlessComboBoxProps,
|
|
17
|
-
type ComboBoxInputProps as HeadlessComboBoxInputProps,
|
|
18
|
-
type ComboBoxButtonProps as HeadlessComboBoxButtonProps,
|
|
19
|
-
type ComboBoxListBoxProps as HeadlessComboBoxListBoxProps,
|
|
20
|
-
type ComboBoxOptionProps as HeadlessComboBoxOptionProps,
|
|
21
|
-
type ComboBoxRenderProps,
|
|
22
|
-
type ComboBoxInputRenderProps,
|
|
23
|
-
type ComboBoxButtonRenderProps,
|
|
24
|
-
type ComboBoxListBoxRenderProps,
|
|
25
|
-
type ComboBoxOptionRenderProps,
|
|
26
|
-
} from '@proyecto-viviana/solidaria-components'
|
|
27
|
-
import type { Key, FilterFn, MenuTriggerAction } from '@proyecto-viviana/solid-stately'
|
|
28
|
-
|
|
29
|
-
// ============================================
|
|
30
|
-
// SIZE CONTEXT
|
|
31
|
-
// ============================================
|
|
32
|
-
|
|
33
|
-
export type ComboBoxSize = 'sm' | 'md' | 'lg'
|
|
34
|
-
|
|
35
|
-
const ComboBoxSizeContext = createContext<ComboBoxSize>('md')
|
|
36
|
-
|
|
37
|
-
// ============================================
|
|
38
|
-
// TYPES
|
|
39
|
-
// ============================================
|
|
40
|
-
|
|
41
|
-
export interface ComboBoxProps<T> extends Omit<HeadlessComboBoxProps<T>, 'class' | 'style'> {
|
|
42
|
-
/** The size of the combobox. */
|
|
43
|
-
size?: ComboBoxSize
|
|
44
|
-
/** Additional CSS class name. */
|
|
45
|
-
class?: string
|
|
46
|
-
/** Label for the combobox. */
|
|
47
|
-
label?: string
|
|
48
|
-
/** Description for the combobox. */
|
|
49
|
-
description?: string
|
|
50
|
-
/** Error message when invalid. */
|
|
51
|
-
errorMessage?: string
|
|
52
|
-
/** Whether the combobox is invalid. */
|
|
53
|
-
isInvalid?: boolean
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
export interface ComboBoxInputProps extends Omit<HeadlessComboBoxInputProps, 'class' | 'style'> {
|
|
57
|
-
/** Additional CSS class name. */
|
|
58
|
-
class?: string
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
export interface ComboBoxButtonProps extends Omit<HeadlessComboBoxButtonProps, 'class' | 'style'> {
|
|
62
|
-
/** Additional CSS class name. */
|
|
63
|
-
class?: string
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
export interface ComboBoxListBoxProps<T> extends Omit<HeadlessComboBoxListBoxProps<T>, 'class' | 'style'> {
|
|
67
|
-
/** Additional CSS class name. */
|
|
68
|
-
class?: string
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
export interface ComboBoxOptionProps<T> extends Omit<HeadlessComboBoxOptionProps<T>, 'class' | 'style'> {
|
|
72
|
-
/** Additional CSS class name. */
|
|
73
|
-
class?: string
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
// ============================================
|
|
77
|
-
// STYLES
|
|
78
|
-
// ============================================
|
|
79
|
-
|
|
80
|
-
const sizeStyles = {
|
|
81
|
-
sm: {
|
|
82
|
-
wrapper: 'h-8',
|
|
83
|
-
input: 'h-8 text-sm pl-3 pr-8',
|
|
84
|
-
button: 'h-8 w-8',
|
|
85
|
-
label: 'text-sm',
|
|
86
|
-
option: 'text-sm py-1.5 px-3',
|
|
87
|
-
icon: 'h-4 w-4',
|
|
88
|
-
},
|
|
89
|
-
md: {
|
|
90
|
-
wrapper: 'h-10',
|
|
91
|
-
input: 'h-10 text-base pl-4 pr-10',
|
|
92
|
-
button: 'h-10 w-10',
|
|
93
|
-
label: 'text-base',
|
|
94
|
-
option: 'text-base py-2 px-4',
|
|
95
|
-
icon: 'h-5 w-5',
|
|
96
|
-
},
|
|
97
|
-
lg: {
|
|
98
|
-
wrapper: 'h-12',
|
|
99
|
-
input: 'h-12 text-lg pl-5 pr-12',
|
|
100
|
-
button: 'h-12 w-12',
|
|
101
|
-
label: 'text-lg',
|
|
102
|
-
option: 'text-lg py-2.5 px-5',
|
|
103
|
-
icon: 'h-6 w-6',
|
|
104
|
-
},
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
// ============================================
|
|
108
|
-
// COMBOBOX COMPONENT
|
|
109
|
-
// ============================================
|
|
110
|
-
|
|
111
|
-
/**
|
|
112
|
-
* A combobox combines a text input with a listbox, allowing users to filter a list of options.
|
|
113
|
-
*
|
|
114
|
-
* Built on solidaria-components ComboBox for full accessibility support.
|
|
115
|
-
*/
|
|
116
|
-
export function ComboBox<T>(props: ComboBoxProps<T>): JSX.Element {
|
|
117
|
-
const [local, headlessProps] = splitProps(props, [
|
|
118
|
-
'size',
|
|
119
|
-
'class',
|
|
120
|
-
'label',
|
|
121
|
-
'description',
|
|
122
|
-
'errorMessage',
|
|
123
|
-
'isInvalid',
|
|
124
|
-
])
|
|
125
|
-
|
|
126
|
-
const size = local.size ?? 'md'
|
|
127
|
-
const customClass = local.class ?? ''
|
|
128
|
-
|
|
129
|
-
const getClassName = (renderProps: ComboBoxRenderProps): string => {
|
|
130
|
-
const base = 'relative inline-flex flex-col gap-1.5'
|
|
131
|
-
const disabledClass = renderProps.isDisabled ? 'opacity-50' : ''
|
|
132
|
-
return [base, disabledClass, customClass].filter(Boolean).join(' ')
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
return (
|
|
136
|
-
<ComboBoxSizeContext.Provider value={size}>
|
|
137
|
-
<HeadlessComboBox
|
|
138
|
-
{...headlessProps}
|
|
139
|
-
class={getClassName}
|
|
140
|
-
>
|
|
141
|
-
<Show when={local.label}>
|
|
142
|
-
<label class={`text-primary-200 font-medium ${sizeStyles[size].label}`}>
|
|
143
|
-
{local.label}
|
|
144
|
-
</label>
|
|
145
|
-
</Show>
|
|
146
|
-
{props.children}
|
|
147
|
-
<Show when={local.description && !local.isInvalid}>
|
|
148
|
-
<span class="text-primary-400 text-sm">{local.description}</span>
|
|
149
|
-
</Show>
|
|
150
|
-
<Show when={local.errorMessage && local.isInvalid}>
|
|
151
|
-
<span class="text-danger-400 text-sm">{local.errorMessage}</span>
|
|
152
|
-
</Show>
|
|
153
|
-
</HeadlessComboBox>
|
|
154
|
-
</ComboBoxSizeContext.Provider>
|
|
155
|
-
)
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
// ============================================
|
|
159
|
-
// COMBOBOX INPUT GROUP COMPONENT
|
|
160
|
-
// ============================================
|
|
161
|
-
|
|
162
|
-
/**
|
|
163
|
-
* A wrapper for the input and button that provides proper styling.
|
|
164
|
-
*/
|
|
165
|
-
export function ComboBoxInputGroup(props: { children: JSX.Element; class?: string }): JSX.Element {
|
|
166
|
-
const size = useContext(ComboBoxSizeContext)
|
|
167
|
-
const styles = () => sizeStyles[size]
|
|
168
|
-
|
|
169
|
-
return (
|
|
170
|
-
<div class={`relative flex items-center ${styles().wrapper} ${props.class ?? ''}`}>
|
|
171
|
-
{props.children}
|
|
172
|
-
</div>
|
|
173
|
-
)
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
// ============================================
|
|
177
|
-
// COMBOBOX INPUT COMPONENT
|
|
178
|
-
// ============================================
|
|
179
|
-
|
|
180
|
-
/**
|
|
181
|
-
* The text input for a combobox.
|
|
182
|
-
*/
|
|
183
|
-
export function ComboBoxInput(props: ComboBoxInputProps): JSX.Element {
|
|
184
|
-
const [local, headlessProps] = splitProps(props, ['class'])
|
|
185
|
-
const size = useContext(ComboBoxSizeContext)
|
|
186
|
-
const styles = () => sizeStyles[size]
|
|
187
|
-
const customClass = local.class ?? ''
|
|
188
|
-
|
|
189
|
-
const getClassName = (renderProps: ComboBoxInputRenderProps): string => {
|
|
190
|
-
const base = 'w-full rounded-lg border-2 transition-all duration-200 outline-none'
|
|
191
|
-
const sizeClass = styles().input
|
|
192
|
-
|
|
193
|
-
let colorClass: string
|
|
194
|
-
if (renderProps.isDisabled) {
|
|
195
|
-
colorClass = 'border-bg-300 bg-bg-200 text-primary-500 cursor-not-allowed'
|
|
196
|
-
} else if (renderProps.isOpen) {
|
|
197
|
-
colorClass = 'border-accent bg-bg-300 text-primary-100'
|
|
198
|
-
} else if (renderProps.isHovered) {
|
|
199
|
-
colorClass = 'border-accent-300 bg-bg-300 text-primary-100'
|
|
200
|
-
} else {
|
|
201
|
-
colorClass = 'border-primary-600 bg-bg-400 text-primary-200'
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
const focusClass = renderProps.isFocusVisible
|
|
205
|
-
? 'ring-2 ring-accent-300 ring-offset-2 ring-offset-bg-400'
|
|
206
|
-
: ''
|
|
207
|
-
|
|
208
|
-
return [base, sizeClass, colorClass, focusClass, customClass].filter(Boolean).join(' ')
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
return (
|
|
212
|
-
<HeadlessComboBoxInput
|
|
213
|
-
{...headlessProps}
|
|
214
|
-
class={getClassName}
|
|
215
|
-
/>
|
|
216
|
-
)
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
// ============================================
|
|
220
|
-
// COMBOBOX BUTTON COMPONENT
|
|
221
|
-
// ============================================
|
|
222
|
-
|
|
223
|
-
/**
|
|
224
|
-
* The trigger button for a combobox.
|
|
225
|
-
* SSR-compatible - renders children or chevron icon directly without render props.
|
|
226
|
-
*/
|
|
227
|
-
export function ComboBoxButton(props: ComboBoxButtonProps): JSX.Element {
|
|
228
|
-
const [local, headlessProps] = splitProps(props, ['class'])
|
|
229
|
-
const size = useContext(ComboBoxSizeContext)
|
|
230
|
-
const sizeStyle = sizeStyles[size]
|
|
231
|
-
const customClass = local.class ?? ''
|
|
232
|
-
|
|
233
|
-
const getClassName = (renderProps: ComboBoxButtonRenderProps): string => {
|
|
234
|
-
const base = 'absolute right-0 top-0 flex items-center justify-center transition-all duration-200 rounded-r-lg'
|
|
235
|
-
const sizeClass = sizeStyle.button
|
|
236
|
-
|
|
237
|
-
let colorClass: string
|
|
238
|
-
if (renderProps.isDisabled) {
|
|
239
|
-
colorClass = 'text-primary-500 cursor-not-allowed'
|
|
240
|
-
} else if (renderProps.isOpen) {
|
|
241
|
-
colorClass = 'text-accent'
|
|
242
|
-
} else if (renderProps.isHovered) {
|
|
243
|
-
colorClass = 'text-accent-300 cursor-pointer'
|
|
244
|
-
} else {
|
|
245
|
-
colorClass = 'text-primary-400 cursor-pointer hover:text-primary-200'
|
|
246
|
-
}
|
|
247
|
-
|
|
248
|
-
return [base, sizeClass, colorClass, customClass].filter(Boolean).join(' ')
|
|
249
|
-
}
|
|
250
|
-
|
|
251
|
-
return (
|
|
252
|
-
<HeadlessComboBoxButton
|
|
253
|
-
{...headlessProps}
|
|
254
|
-
class={getClassName}
|
|
255
|
-
>
|
|
256
|
-
{props.children || <ChevronIcon class={`${sizeStyle.icon} transition-transform duration-200 data-open:rotate-180`} />}
|
|
257
|
-
</HeadlessComboBoxButton>
|
|
258
|
-
)
|
|
259
|
-
}
|
|
260
|
-
|
|
261
|
-
// ============================================
|
|
262
|
-
// COMBOBOX LISTBOX COMPONENT
|
|
263
|
-
// ============================================
|
|
264
|
-
|
|
265
|
-
/**
|
|
266
|
-
* The listbox popup for a combobox.
|
|
267
|
-
*/
|
|
268
|
-
export function ComboBoxListBox<T>(props: ComboBoxListBoxProps<T>): JSX.Element {
|
|
269
|
-
const [local, headlessProps] = splitProps(props, ['class'])
|
|
270
|
-
const customClass = local.class ?? ''
|
|
271
|
-
|
|
272
|
-
const getClassName = (_renderProps: ComboBoxListBoxRenderProps): string => {
|
|
273
|
-
const base = 'absolute z-50 mt-1 w-full rounded-lg border-2 border-primary-600 bg-bg-400 py-1 shadow-lg max-h-60 overflow-auto'
|
|
274
|
-
return [base, customClass].filter(Boolean).join(' ')
|
|
275
|
-
}
|
|
276
|
-
|
|
277
|
-
return (
|
|
278
|
-
<HeadlessComboBoxListBox
|
|
279
|
-
{...headlessProps}
|
|
280
|
-
class={getClassName}
|
|
281
|
-
children={props.children}
|
|
282
|
-
/>
|
|
283
|
-
)
|
|
284
|
-
}
|
|
285
|
-
|
|
286
|
-
// ============================================
|
|
287
|
-
// COMBOBOX OPTION COMPONENT
|
|
288
|
-
// ============================================
|
|
289
|
-
|
|
290
|
-
/**
|
|
291
|
-
* An option in a combobox listbox.
|
|
292
|
-
* SSR-compatible - renders check icon and content directly without render props.
|
|
293
|
-
*/
|
|
294
|
-
export function ComboBoxOption<T>(props: ComboBoxOptionProps<T>): JSX.Element {
|
|
295
|
-
const [local, headlessProps] = splitProps(props, ['class'])
|
|
296
|
-
const size = useContext(ComboBoxSizeContext)
|
|
297
|
-
const sizeStyle = sizeStyles[size]
|
|
298
|
-
const customClass = local.class ?? ''
|
|
299
|
-
|
|
300
|
-
const getClassName = (renderProps: ComboBoxOptionRenderProps): string => {
|
|
301
|
-
const base = 'flex items-center gap-2 cursor-pointer transition-colors duration-150'
|
|
302
|
-
const sizeClass = sizeStyle.option
|
|
303
|
-
|
|
304
|
-
let colorClass: string
|
|
305
|
-
if (renderProps.isDisabled) {
|
|
306
|
-
colorClass = 'text-primary-500 cursor-not-allowed'
|
|
307
|
-
} else if (renderProps.isSelected) {
|
|
308
|
-
colorClass = 'bg-accent/20 text-accent'
|
|
309
|
-
} else if (renderProps.isFocused || renderProps.isHovered) {
|
|
310
|
-
colorClass = 'bg-bg-300 text-primary-100'
|
|
311
|
-
} else {
|
|
312
|
-
colorClass = 'text-primary-200'
|
|
313
|
-
}
|
|
314
|
-
|
|
315
|
-
const focusClass = renderProps.isFocusVisible
|
|
316
|
-
? 'ring-2 ring-inset ring-accent-300'
|
|
317
|
-
: ''
|
|
318
|
-
|
|
319
|
-
return [base, sizeClass, colorClass, focusClass, customClass].filter(Boolean).join(' ')
|
|
320
|
-
}
|
|
321
|
-
|
|
322
|
-
// Compute padding for non-selected items to align with check icon
|
|
323
|
-
const iconPadding: Record<ComboBoxSize, string> = {
|
|
324
|
-
sm: 'pl-6', // h-4 icon + gap
|
|
325
|
-
md: 'pl-7', // h-5 icon + gap
|
|
326
|
-
lg: 'pl-8', // h-6 icon + gap
|
|
327
|
-
}
|
|
328
|
-
|
|
329
|
-
return (
|
|
330
|
-
<HeadlessComboBoxOption
|
|
331
|
-
{...headlessProps}
|
|
332
|
-
class={getClassName}
|
|
333
|
-
>
|
|
334
|
-
<CheckIcon class={`${sizeStyle.icon} text-accent shrink-0 hidden data-selected:block`} />
|
|
335
|
-
<span class={`flex-1 data-selected:pl-0 ${iconPadding[size]}`}>
|
|
336
|
-
{props.children as JSX.Element}
|
|
337
|
-
</span>
|
|
338
|
-
</HeadlessComboBoxOption>
|
|
339
|
-
)
|
|
340
|
-
}
|
|
341
|
-
|
|
342
|
-
// ============================================
|
|
343
|
-
// ICONS
|
|
344
|
-
// ============================================
|
|
345
|
-
|
|
346
|
-
function ChevronIcon(props: { class?: string }): JSX.Element {
|
|
347
|
-
return (
|
|
348
|
-
<svg
|
|
349
|
-
class={props.class}
|
|
350
|
-
fill="none"
|
|
351
|
-
viewBox="0 0 24 24"
|
|
352
|
-
stroke="currentColor"
|
|
353
|
-
stroke-width="2"
|
|
354
|
-
>
|
|
355
|
-
<path stroke-linecap="round" stroke-linejoin="round" d="M19 9l-7 7-7-7" />
|
|
356
|
-
</svg>
|
|
357
|
-
)
|
|
358
|
-
}
|
|
359
|
-
|
|
360
|
-
function CheckIcon(props: { class?: string }): JSX.Element {
|
|
361
|
-
return (
|
|
362
|
-
<svg
|
|
363
|
-
class={props.class}
|
|
364
|
-
fill="none"
|
|
365
|
-
viewBox="0 0 24 24"
|
|
366
|
-
stroke="currentColor"
|
|
367
|
-
stroke-width="2"
|
|
368
|
-
>
|
|
369
|
-
<path stroke-linecap="round" stroke-linejoin="round" d="M5 13l4 4L19 7" />
|
|
370
|
-
</svg>
|
|
371
|
-
)
|
|
372
|
-
}
|
|
373
|
-
|
|
374
|
-
// Attach sub-components for convenience
|
|
375
|
-
ComboBox.InputGroup = ComboBoxInputGroup
|
|
376
|
-
ComboBox.Input = ComboBoxInput
|
|
377
|
-
ComboBox.Button = ComboBoxButton
|
|
378
|
-
ComboBox.ListBox = ComboBoxListBox
|
|
379
|
-
ComboBox.Option = ComboBoxOption
|
|
380
|
-
|
|
381
|
-
// Re-export types and utilities for convenience
|
|
382
|
-
export type { Key, FilterFn, MenuTriggerAction }
|
|
383
|
-
export { defaultContainsFilter }
|
package/src/dialog/Dialog.tsx
DELETED
|
@@ -1,260 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Dialog component for proyecto-viviana-ui
|
|
3
|
-
*
|
|
4
|
-
* Styled dialog component with overlay and backdrop.
|
|
5
|
-
* Follows Spectrum 2 design patterns.
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
import { type JSX, splitProps, Show, createSignal, createContext, useContext, createUniqueId, onMount, onCleanup, createEffect } from 'solid-js'
|
|
9
|
-
import { Portal } from 'solid-js/web'
|
|
10
|
-
import { createInteractOutside } from '@proyecto-viviana/solidaria'
|
|
11
|
-
|
|
12
|
-
// ============================================
|
|
13
|
-
// TYPES
|
|
14
|
-
// ============================================
|
|
15
|
-
|
|
16
|
-
export type DialogSize = 'sm' | 'md' | 'lg' | 'fullscreen'
|
|
17
|
-
|
|
18
|
-
export interface DialogProps {
|
|
19
|
-
/** The size of the dialog. */
|
|
20
|
-
size?: DialogSize
|
|
21
|
-
/** Whether the dialog can be dismissed by clicking the X button. */
|
|
22
|
-
isDismissable?: boolean
|
|
23
|
-
/** Additional CSS class name. */
|
|
24
|
-
class?: string
|
|
25
|
-
/** The title of the dialog. */
|
|
26
|
-
title?: string
|
|
27
|
-
/** The children content. */
|
|
28
|
-
children: JSX.Element
|
|
29
|
-
/** Callback when dialog should close */
|
|
30
|
-
onClose?: () => void
|
|
31
|
-
/** ARIA role - defaults to 'dialog' */
|
|
32
|
-
role?: 'dialog' | 'alertdialog'
|
|
33
|
-
/** ARIA label */
|
|
34
|
-
'aria-label'?: string
|
|
35
|
-
/** ARIA labelledby */
|
|
36
|
-
'aria-labelledby'?: string
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
export interface DialogTriggerProps {
|
|
40
|
-
/** Button to trigger the dialog. */
|
|
41
|
-
trigger: JSX.Element
|
|
42
|
-
/** The dialog content - receives close function. */
|
|
43
|
-
content: (close: () => void) => JSX.Element
|
|
44
|
-
/** Whether the dialog is controlled. */
|
|
45
|
-
isOpen?: boolean
|
|
46
|
-
/** Callback when open state changes. */
|
|
47
|
-
onOpenChange?: (isOpen: boolean) => void
|
|
48
|
-
/** Whether clicking outside the dialog closes it. Defaults to true. */
|
|
49
|
-
isDismissable?: boolean
|
|
50
|
-
/** Whether pressing Escape closes the dialog. Defaults to true. */
|
|
51
|
-
isKeyboardDismissDisabled?: boolean
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
// ============================================
|
|
55
|
-
// CONTEXT
|
|
56
|
-
// ============================================
|
|
57
|
-
|
|
58
|
-
interface DialogContextValue {
|
|
59
|
-
close: () => void
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
const DialogContext = createContext<DialogContextValue | null>(null)
|
|
63
|
-
|
|
64
|
-
export function useDialogContext(): DialogContextValue | null {
|
|
65
|
-
return useContext(DialogContext)
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
// ============================================
|
|
69
|
-
// STYLES
|
|
70
|
-
// ============================================
|
|
71
|
-
|
|
72
|
-
const sizeStyles: Record<DialogSize, string> = {
|
|
73
|
-
sm: 'max-w-sm',
|
|
74
|
-
md: 'max-w-md',
|
|
75
|
-
lg: 'max-w-2xl',
|
|
76
|
-
fullscreen: 'max-w-full w-full h-full',
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
// ============================================
|
|
80
|
-
// DIALOG COMPONENT
|
|
81
|
-
// ============================================
|
|
82
|
-
|
|
83
|
-
/**
|
|
84
|
-
* A dialog is an overlay shown above other content in an application.
|
|
85
|
-
*/
|
|
86
|
-
export function Dialog(props: DialogProps): JSX.Element {
|
|
87
|
-
const [local, rest] = splitProps(props, [
|
|
88
|
-
'size',
|
|
89
|
-
'isDismissable',
|
|
90
|
-
'class',
|
|
91
|
-
'title',
|
|
92
|
-
'onClose',
|
|
93
|
-
'role',
|
|
94
|
-
'aria-label',
|
|
95
|
-
'aria-labelledby',
|
|
96
|
-
])
|
|
97
|
-
|
|
98
|
-
const size = local.size ?? 'md'
|
|
99
|
-
const customClass = local.class ?? ''
|
|
100
|
-
const role = local.role ?? 'dialog'
|
|
101
|
-
|
|
102
|
-
// Generate a unique ID for the title if one is present
|
|
103
|
-
const titleId = createUniqueId()
|
|
104
|
-
const ariaLabelledBy = local['aria-labelledby'] ?? (local.title ? titleId : undefined)
|
|
105
|
-
|
|
106
|
-
const close = () => local.onClose?.()
|
|
107
|
-
|
|
108
|
-
const baseClass = 'bg-bg-300 rounded-lg shadow-xl border border-primary-700'
|
|
109
|
-
const sizeClass = sizeStyles[size]
|
|
110
|
-
const padding = 'p-6'
|
|
111
|
-
const className = [baseClass, sizeClass, padding, customClass].filter(Boolean).join(' ')
|
|
112
|
-
|
|
113
|
-
return (
|
|
114
|
-
<DialogContext.Provider value={{ close }}>
|
|
115
|
-
<div
|
|
116
|
-
role={role}
|
|
117
|
-
tabIndex={-1}
|
|
118
|
-
aria-label={local['aria-label']}
|
|
119
|
-
aria-labelledby={ariaLabelledBy}
|
|
120
|
-
class={className}
|
|
121
|
-
{...rest}
|
|
122
|
-
>
|
|
123
|
-
<Show when={local.title}>
|
|
124
|
-
<div class="flex items-center justify-between mb-4">
|
|
125
|
-
<h2 id={titleId} class="text-xl font-semibold text-primary-100">
|
|
126
|
-
{local.title}
|
|
127
|
-
</h2>
|
|
128
|
-
<Show when={local.isDismissable}>
|
|
129
|
-
<button
|
|
130
|
-
onClick={close}
|
|
131
|
-
class="text-primary-400 hover:text-primary-200 transition-colors"
|
|
132
|
-
aria-label="Close dialog"
|
|
133
|
-
>
|
|
134
|
-
<svg class="w-5 h-5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
|
135
|
-
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12" />
|
|
136
|
-
</svg>
|
|
137
|
-
</button>
|
|
138
|
-
</Show>
|
|
139
|
-
</div>
|
|
140
|
-
</Show>
|
|
141
|
-
<div class="text-primary-200">
|
|
142
|
-
{props.children}
|
|
143
|
-
</div>
|
|
144
|
-
</div>
|
|
145
|
-
</DialogContext.Provider>
|
|
146
|
-
)
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
// ============================================
|
|
150
|
-
// DIALOG TRIGGER COMPONENT
|
|
151
|
-
// ============================================
|
|
152
|
-
|
|
153
|
-
/**
|
|
154
|
-
* DialogTrigger wraps a trigger button and dialog content.
|
|
155
|
-
* Handles opening/closing the dialog with overlay and backdrop.
|
|
156
|
-
*/
|
|
157
|
-
export function DialogTrigger(props: DialogTriggerProps): JSX.Element {
|
|
158
|
-
const [isOpen, setIsOpen] = createSignal(props.isOpen ?? false)
|
|
159
|
-
let dialogRef: HTMLDivElement | undefined
|
|
160
|
-
|
|
161
|
-
const open = () => {
|
|
162
|
-
setIsOpen(true)
|
|
163
|
-
props.onOpenChange?.(true)
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
const close = () => {
|
|
167
|
-
setIsOpen(false)
|
|
168
|
-
props.onOpenChange?.(false)
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
// Handle controlled state
|
|
172
|
-
const isOpenControlled = () => props.isOpen !== undefined ? props.isOpen : isOpen()
|
|
173
|
-
|
|
174
|
-
// Whether dismissable (defaults to true)
|
|
175
|
-
const isDismissable = () => props.isDismissable !== false
|
|
176
|
-
|
|
177
|
-
// Click outside to close
|
|
178
|
-
createInteractOutside({
|
|
179
|
-
ref: () => dialogRef ?? null,
|
|
180
|
-
onInteractOutside: () => {
|
|
181
|
-
if (isOpenControlled() && isDismissable()) {
|
|
182
|
-
close()
|
|
183
|
-
}
|
|
184
|
-
},
|
|
185
|
-
isDisabled: !isOpenControlled() || !isDismissable(),
|
|
186
|
-
})
|
|
187
|
-
|
|
188
|
-
// Escape key to close
|
|
189
|
-
onMount(() => {
|
|
190
|
-
const handleKeyDown = (e: KeyboardEvent) => {
|
|
191
|
-
if (e.key === 'Escape' && isOpenControlled() && !props.isKeyboardDismissDisabled) {
|
|
192
|
-
e.preventDefault()
|
|
193
|
-
e.stopPropagation()
|
|
194
|
-
close()
|
|
195
|
-
}
|
|
196
|
-
}
|
|
197
|
-
document.addEventListener('keydown', handleKeyDown)
|
|
198
|
-
onCleanup(() => document.removeEventListener('keydown', handleKeyDown))
|
|
199
|
-
})
|
|
200
|
-
|
|
201
|
-
// Prevent background scroll when dialog is open
|
|
202
|
-
createEffect(() => {
|
|
203
|
-
if (!isOpenControlled()) return
|
|
204
|
-
|
|
205
|
-
const prevOverflow = document.documentElement.style.overflow
|
|
206
|
-
document.documentElement.style.overflow = 'hidden'
|
|
207
|
-
|
|
208
|
-
onCleanup(() => {
|
|
209
|
-
document.documentElement.style.overflow = prevOverflow
|
|
210
|
-
})
|
|
211
|
-
})
|
|
212
|
-
|
|
213
|
-
return (
|
|
214
|
-
<>
|
|
215
|
-
<div onClick={open}>
|
|
216
|
-
{props.trigger}
|
|
217
|
-
</div>
|
|
218
|
-
|
|
219
|
-
<Show when={isOpenControlled()}>
|
|
220
|
-
<Portal>
|
|
221
|
-
{/* Backdrop */}
|
|
222
|
-
<div
|
|
223
|
-
class="fixed inset-0 bg-black/50 backdrop-blur-sm z-40"
|
|
224
|
-
aria-hidden="true"
|
|
225
|
-
/>
|
|
226
|
-
|
|
227
|
-
{/* Dialog container - pointer-events-none so clicks pass through to backdrop detection */}
|
|
228
|
-
<div class="fixed inset-0 z-50 flex items-center justify-center p-4 pointer-events-none">
|
|
229
|
-
{/* Dialog wrapper - pointer-events-auto to capture clicks on the dialog itself */}
|
|
230
|
-
<div ref={dialogRef} class="pointer-events-auto">
|
|
231
|
-
{props.content(close)}
|
|
232
|
-
</div>
|
|
233
|
-
</div>
|
|
234
|
-
</Portal>
|
|
235
|
-
</Show>
|
|
236
|
-
</>
|
|
237
|
-
)
|
|
238
|
-
}
|
|
239
|
-
|
|
240
|
-
// ============================================
|
|
241
|
-
// DIALOG FOOTER COMPONENT
|
|
242
|
-
// ============================================
|
|
243
|
-
|
|
244
|
-
export interface DialogFooterProps {
|
|
245
|
-
/** Footer content, typically buttons. */
|
|
246
|
-
children: JSX.Element
|
|
247
|
-
/** Additional CSS class. */
|
|
248
|
-
class?: string
|
|
249
|
-
}
|
|
250
|
-
|
|
251
|
-
/**
|
|
252
|
-
* Footer section for dialog actions.
|
|
253
|
-
*/
|
|
254
|
-
export function DialogFooter(props: DialogFooterProps): JSX.Element {
|
|
255
|
-
return (
|
|
256
|
-
<div class={`flex gap-3 justify-end mt-6 pt-4 border-t border-primary-700 ${props.class ?? ''}`}>
|
|
257
|
-
{props.children}
|
|
258
|
-
</div>
|
|
259
|
-
)
|
|
260
|
-
}
|
package/src/dialog/index.tsx
DELETED