@ahrowe/ui 0.41.2 → 0.43.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/CHANGELOG.md +934 -0
- package/README.md +11 -10
- package/dist/cjs-types/common/accordion/accordion.types.d.ts +17 -2
- package/dist/cjs-types/common/actionButtons/actionButtons.types.d.ts +7 -1
- package/dist/cjs-types/common/actionIcon/actionIcon.d.ts +1 -1
- package/dist/cjs-types/common/actionIcon/actionIcon.types.d.ts +7 -9
- package/dist/cjs-types/common/alert/alert.types.d.ts +6 -8
- package/dist/cjs-types/common/animatedLogo/animatedLogo.types.d.ts +3 -2
- package/dist/cjs-types/common/badge/badge.types.d.ts +10 -6
- package/dist/cjs-types/common/button/button.types.d.ts +14 -4
- package/dist/cjs-types/common/calendar/calendar.types.d.ts +25 -10
- package/dist/cjs-types/common/calendar/components/agendaList/agendaList.d.ts +1 -1
- package/dist/cjs-types/common/calendar/components/agendaList/agendaList.types.d.ts +3 -0
- package/dist/cjs-types/common/calendar/components/calendarHeader/calendarHeader.d.ts +1 -1
- package/dist/cjs-types/common/calendar/components/calendarHeader/calendarHeader.types.d.ts +2 -0
- package/dist/cjs-types/common/calendar/components/compactMonth/compactMonth.d.ts +1 -1
- package/dist/cjs-types/common/calendar/components/monthView/monthView.d.ts +1 -1
- package/dist/cjs-types/common/calendar/components/monthView/monthView.types.d.ts +3 -2
- package/dist/cjs-types/common/calendar/components/timeGrid/timeGrid.d.ts +1 -1
- package/dist/cjs-types/common/calendar/components/timeGrid/timeGrid.types.d.ts +9 -1
- package/dist/cjs-types/common/calendar/dates.d.ts +21 -5
- package/dist/cjs-types/common/calendar/format.d.ts +3 -2
- package/dist/cjs-types/common/calendar/layout.d.ts +5 -0
- package/dist/cjs-types/common/calendar/useNow.d.ts +4 -0
- package/dist/cjs-types/common/calendar/view.types.d.ts +9 -2
- package/dist/cjs-types/common/card/card.types.d.ts +16 -2
- package/dist/cjs-types/common/chip/chip.types.d.ts +10 -5
- package/dist/cjs-types/common/copyButton/copyButton.types.d.ts +5 -4
- package/dist/cjs-types/common/fab/components/fabBase/fabBase.d.ts +1 -1
- package/dist/cjs-types/common/fab/components/fabBase/fabBase.types.d.ts +2 -1
- package/dist/cjs-types/common/floorPlan/floorPlan.graph.d.ts +10 -3
- package/dist/cjs-types/common/floorPlan/floorPlan.plan.d.ts +5 -0
- package/dist/cjs-types/common/floorPlan/floorPlan.rooms.d.ts +6 -2
- package/dist/cjs-types/common/floorPlan/floorPlan.snap.d.ts +1 -3
- package/dist/cjs-types/common/floorPlan/index.d.ts +1 -3
- package/dist/cjs-types/common/planCanvas/planCanvas.types.d.ts +1 -1
- package/dist/cjs-types/common/progressBar/progressBar.d.ts +0 -1
- package/dist/cjs-types/common/progressBar/progressBar.types.d.ts +3 -1
- package/dist/cjs-types/common/roomDrawer/roomDrawer.types.d.ts +29 -8
- package/dist/cjs-types/common/roomViewer/roomViewer.types.d.ts +4 -2
- package/dist/cjs-types/common/splitButton/splitButton.types.d.ts +4 -1
- package/dist/cjs-types/common/styles/tone.d.ts +11 -0
- package/dist/cjs-types/common/themeProvider/color.types.d.ts +20 -0
- package/dist/cjs-types/common/themeProvider/index.d.ts +2 -0
- package/dist/cjs-types/common/themeProvider/theme.types.d.ts +3 -6
- package/dist/cjs-types/common/timeline/timeline.types.d.ts +3 -10
- package/dist/cjs-types/common/toast/index.d.ts +1 -1
- package/dist/cjs-types/common/toast/toast.types.d.ts +7 -3
- package/dist/cjs-types/common/types/actions.types.d.ts +1 -1
- package/dist/cjs-types/common/utils/dismissClick.d.ts +4 -0
- package/dist/cjs-types/common/utils/isDev.d.ts +1 -0
- package/dist/esm/common/accordion/accordion.mjs +1 -1
- package/dist/esm/common/accordion/accordion.mjs.map +1 -1
- package/dist/esm/common/accordion/accordion.module.mjs +1 -1
- package/dist/esm/common/accordion/accordion.module.mjs.map +1 -1
- package/dist/esm/common/accordion/accordion.types.mjs +1 -1
- package/dist/esm/common/accordion/accordion.types.mjs.map +1 -1
- package/dist/esm/common/actionButtons/actionButtons.mjs +1 -1
- package/dist/esm/common/actionButtons/actionButtons.mjs.map +1 -1
- package/dist/esm/common/actionIcon/actionIcon.mjs +1 -1
- package/dist/esm/common/actionIcon/actionIcon.mjs.map +1 -1
- package/dist/esm/common/actionIcon/actionIcon.module.mjs +1 -1
- package/dist/esm/common/actionIcon/actionIcon.module.mjs.map +1 -1
- package/dist/esm/common/alert/alert.mjs +1 -1
- package/dist/esm/common/alert/alert.mjs.map +1 -1
- package/dist/esm/common/alert/alert.module.mjs +1 -1
- package/dist/esm/common/alert/alert.module.mjs.map +1 -1
- package/dist/esm/common/animatedLogo/animatedLogo.mjs +1 -1
- package/dist/esm/common/animatedLogo/animatedLogo.mjs.map +1 -1
- package/dist/esm/common/avatar/avatar.mjs +1 -1
- package/dist/esm/common/avatar/avatar.mjs.map +1 -1
- package/dist/esm/common/badge/badge.mjs +1 -1
- package/dist/esm/common/badge/badge.mjs.map +1 -1
- package/dist/esm/common/badge/badge.module.mjs +1 -1
- package/dist/esm/common/badge/badge.module.mjs.map +1 -1
- package/dist/esm/common/badge/badge.types.mjs +1 -1
- package/dist/esm/common/badge/badge.types.mjs.map +1 -1
- package/dist/esm/common/bodyEnd/bodyEnd.mjs +1 -1
- package/dist/esm/common/bodyEnd/bodyEnd.mjs.map +1 -1
- package/dist/esm/common/breadcrumb/breadcrumb.mjs +1 -1
- package/dist/esm/common/breadcrumb/breadcrumb.mjs.map +1 -1
- package/dist/esm/common/breadcrumb/breadcrumb.module.mjs.map +1 -1
- package/dist/esm/common/button/button.mjs +1 -1
- package/dist/esm/common/button/button.mjs.map +1 -1
- package/dist/esm/common/button/button.module.mjs +1 -1
- package/dist/esm/common/button/button.module.mjs.map +1 -1
- package/dist/esm/common/button/button.types.mjs +1 -1
- package/dist/esm/common/button/button.types.mjs.map +1 -1
- package/dist/esm/common/calendar/calendar.mjs +1 -1
- package/dist/esm/common/calendar/calendar.mjs.map +1 -1
- package/dist/esm/common/calendar/calendar.module.mjs.map +1 -1
- package/dist/esm/common/calendar/calendar.types.mjs.map +1 -1
- package/dist/esm/common/calendar/components/agendaList/agendaList.mjs +1 -1
- package/dist/esm/common/calendar/components/agendaList/agendaList.mjs.map +1 -1
- package/dist/esm/common/calendar/components/agendaList/agendaList.module.mjs.map +1 -1
- package/dist/esm/common/calendar/components/calendarHeader/calendarHeader.mjs +1 -1
- package/dist/esm/common/calendar/components/calendarHeader/calendarHeader.mjs.map +1 -1
- package/dist/esm/common/calendar/components/calendarHeader/calendarHeader.module.mjs +1 -1
- package/dist/esm/common/calendar/components/calendarHeader/calendarHeader.module.mjs.map +1 -1
- package/dist/esm/common/calendar/components/compactMonth/compactMonth.mjs +1 -1
- package/dist/esm/common/calendar/components/compactMonth/compactMonth.mjs.map +1 -1
- package/dist/esm/common/calendar/components/compactMonth/compactMonth.module.mjs +1 -1
- package/dist/esm/common/calendar/components/compactMonth/compactMonth.module.mjs.map +1 -1
- package/dist/esm/common/calendar/components/monthView/monthView.mjs +1 -1
- package/dist/esm/common/calendar/components/monthView/monthView.mjs.map +1 -1
- package/dist/esm/common/calendar/components/monthView/monthView.module.mjs +1 -1
- package/dist/esm/common/calendar/components/monthView/monthView.module.mjs.map +1 -1
- package/dist/esm/common/calendar/components/timeGrid/timeGrid.mjs +1 -1
- package/dist/esm/common/calendar/components/timeGrid/timeGrid.mjs.map +1 -1
- package/dist/esm/common/calendar/components/timeGrid/timeGrid.module.mjs +1 -1
- package/dist/esm/common/calendar/components/timeGrid/timeGrid.module.mjs.map +1 -1
- package/dist/esm/common/calendar/dates.mjs +1 -1
- package/dist/esm/common/calendar/dates.mjs.map +1 -1
- package/dist/esm/common/calendar/format.mjs +1 -1
- package/dist/esm/common/calendar/format.mjs.map +1 -1
- package/dist/esm/common/calendar/layout.mjs +1 -1
- package/dist/esm/common/calendar/layout.mjs.map +1 -1
- package/dist/esm/common/calendar/useNow.mjs +2 -0
- package/dist/esm/common/calendar/useNow.mjs.map +1 -0
- package/dist/esm/common/card/Card.mjs +1 -1
- package/dist/esm/common/card/Card.mjs.map +1 -1
- package/dist/esm/common/card/CardActions.mjs +1 -1
- package/dist/esm/common/card/CardActions.mjs.map +1 -1
- package/dist/esm/common/card/CardHeader.mjs.map +1 -1
- package/dist/esm/common/card/card.module.mjs +1 -1
- package/dist/esm/common/card/card.module.mjs.map +1 -1
- package/dist/esm/common/card/card.types.mjs +1 -1
- package/dist/esm/common/card/card.types.mjs.map +1 -1
- package/dist/esm/common/carousel/carousel.mjs +1 -1
- package/dist/esm/common/carousel/carousel.mjs.map +1 -1
- package/dist/esm/common/carousel/carousel.module.mjs.map +1 -1
- package/dist/esm/common/chip/chip.mjs +1 -1
- package/dist/esm/common/chip/chip.mjs.map +1 -1
- package/dist/esm/common/chip/chip.module.mjs +1 -1
- package/dist/esm/common/chip/chip.module.mjs.map +1 -1
- package/dist/esm/common/chip/chip.types.mjs +1 -1
- package/dist/esm/common/chip/chip.types.mjs.map +1 -1
- package/dist/esm/common/colorPicker/colorPicker.mjs +1 -1
- package/dist/esm/common/colorPicker/colorPicker.mjs.map +1 -1
- package/dist/esm/common/colorPicker/colorPicker.module.mjs.map +1 -1
- package/dist/esm/common/confirmModal/confirmModal.mjs +1 -1
- package/dist/esm/common/confirmModal/confirmModal.mjs.map +1 -1
- package/dist/esm/common/copyButton/copyButton.mjs +1 -1
- package/dist/esm/common/copyButton/copyButton.mjs.map +1 -1
- package/dist/esm/common/copyButton/copyButton.module.mjs +1 -1
- package/dist/esm/common/copyButton/copyButton.module.mjs.map +1 -1
- package/dist/esm/common/errorBoundary/errorBoundary.mjs +2 -2
- package/dist/esm/common/errorBoundary/errorBoundary.mjs.map +1 -1
- package/dist/esm/common/fab/components/fabBase/fabBase.mjs +1 -1
- package/dist/esm/common/fab/components/fabBase/fabBase.mjs.map +1 -1
- package/dist/esm/common/fab/fab.mjs +1 -1
- package/dist/esm/common/fab/fab.mjs.map +1 -1
- package/dist/esm/common/flip/flip.mjs +1 -1
- package/dist/esm/common/flip/flip.mjs.map +1 -1
- package/dist/esm/common/floorPlan/floorPlan.faces.mjs +1 -1
- package/dist/esm/common/floorPlan/floorPlan.faces.mjs.map +1 -1
- package/dist/esm/common/floorPlan/floorPlan.geometry.mjs +1 -1
- package/dist/esm/common/floorPlan/floorPlan.geometry.mjs.map +1 -1
- package/dist/esm/common/floorPlan/floorPlan.graph.mjs +1 -1
- package/dist/esm/common/floorPlan/floorPlan.graph.mjs.map +1 -1
- package/dist/esm/common/floorPlan/floorPlan.hit.mjs +1 -1
- package/dist/esm/common/floorPlan/floorPlan.hit.mjs.map +1 -1
- package/dist/esm/common/floorPlan/floorPlan.json.mjs +1 -1
- package/dist/esm/common/floorPlan/floorPlan.json.mjs.map +1 -1
- package/dist/esm/common/floorPlan/floorPlan.mesh.mjs +1 -1
- package/dist/esm/common/floorPlan/floorPlan.mesh.mjs.map +1 -1
- package/dist/esm/common/floorPlan/floorPlan.path.mjs +1 -1
- package/dist/esm/common/floorPlan/floorPlan.path.mjs.map +1 -1
- package/dist/esm/common/floorPlan/floorPlan.plan.mjs +1 -1
- package/dist/esm/common/floorPlan/floorPlan.plan.mjs.map +1 -1
- package/dist/esm/common/floorPlan/floorPlan.rooms.mjs +1 -1
- package/dist/esm/common/floorPlan/floorPlan.rooms.mjs.map +1 -1
- package/dist/esm/common/floorPlan/floorPlan.snap.mjs +1 -1
- package/dist/esm/common/floorPlan/floorPlan.snap.mjs.map +1 -1
- package/dist/esm/common/floorPlan/floorPlan.triangulate.mjs +1 -1
- package/dist/esm/common/floorPlan/floorPlan.triangulate.mjs.map +1 -1
- package/dist/esm/common/floorPlan/floorPlan.types.mjs +1 -1
- package/dist/esm/common/floorPlan/floorPlan.types.mjs.map +1 -1
- package/dist/esm/common/klipyPicker/klipyPicker.mjs +1 -1
- package/dist/esm/common/klipyPicker/klipyPicker.mjs.map +1 -1
- package/dist/esm/common/modal/modal.mjs +1 -1
- package/dist/esm/common/modal/modal.mjs.map +1 -1
- package/dist/esm/common/modal/modal.module.mjs.map +1 -1
- package/dist/esm/common/numberInput/numberInput.mjs +1 -1
- package/dist/esm/common/numberInput/numberInput.mjs.map +1 -1
- package/dist/esm/common/numberInput/numberInput.module.mjs.map +1 -1
- package/dist/esm/common/planCanvas/planCanvas.mjs +1 -1
- package/dist/esm/common/planCanvas/planCanvas.mjs.map +1 -1
- package/dist/esm/common/popover/popover.mjs +1 -1
- package/dist/esm/common/popover/popover.mjs.map +1 -1
- package/dist/esm/common/progressBar/progressBar.mjs +1 -1
- package/dist/esm/common/progressBar/progressBar.mjs.map +1 -1
- package/dist/esm/common/progressBar/progressBar.module.mjs +1 -1
- package/dist/esm/common/progressBar/progressBar.module.mjs.map +1 -1
- package/dist/esm/common/roomDrawer/roomDrawer.mjs +1 -1
- package/dist/esm/common/roomDrawer/roomDrawer.mjs.map +1 -1
- package/dist/esm/common/roomDrawer/roomDrawer.module.mjs.map +1 -1
- package/dist/esm/common/roomViewer/roomViewer.mjs +1 -1
- package/dist/esm/common/roomViewer/roomViewer.mjs.map +1 -1
- package/dist/esm/common/sectionHeader/sectionHeader.mjs.map +1 -1
- package/dist/esm/common/splitButton/splitButton.mjs +1 -1
- package/dist/esm/common/splitButton/splitButton.mjs.map +1 -1
- package/dist/esm/common/styles/tone.mjs +4 -0
- package/dist/esm/common/styles/tone.mjs.map +1 -0
- package/dist/esm/common/styles/tone.module.mjs +2 -0
- package/dist/esm/common/styles/tone.module.mjs.map +1 -0
- package/dist/esm/common/themeProvider/color.types.mjs +2 -0
- package/dist/esm/common/themeProvider/color.types.mjs.map +1 -0
- package/dist/esm/common/themeProvider/defaultTheme.mjs +1 -1
- package/dist/esm/common/themeProvider/defaultTheme.mjs.map +1 -1
- package/dist/esm/common/tilt/tilt.mjs +1 -1
- package/dist/esm/common/tilt/tilt.mjs.map +1 -1
- package/dist/esm/common/timeInput/timeInput.mjs +1 -1
- package/dist/esm/common/timeInput/timeInput.mjs.map +1 -1
- package/dist/esm/common/timeline/timeline.mjs +1 -1
- package/dist/esm/common/timeline/timeline.mjs.map +1 -1
- package/dist/esm/common/timeline/timeline.module.mjs +1 -1
- package/dist/esm/common/timeline/timeline.module.mjs.map +1 -1
- package/dist/esm/common/timeline/timeline.types.mjs +1 -1
- package/dist/esm/common/timeline/timeline.types.mjs.map +1 -1
- package/dist/esm/common/timer/timer.mjs +1 -1
- package/dist/esm/common/timer/timer.mjs.map +1 -1
- package/dist/esm/common/timer/timer.module.mjs +1 -1
- package/dist/esm/common/timer/timer.module.mjs.map +1 -1
- package/dist/esm/common/toast/toast.mjs +1 -1
- package/dist/esm/common/toast/toast.mjs.map +1 -1
- package/dist/esm/common/toast/toast.module.mjs +1 -1
- package/dist/esm/common/toast/toast.module.mjs.map +1 -1
- package/dist/esm/common/toast/toastHost.mjs +1 -1
- package/dist/esm/common/toast/toastHost.mjs.map +1 -1
- package/dist/esm/common/utils/dismissClick.mjs +2 -0
- package/dist/esm/common/utils/dismissClick.mjs.map +1 -0
- package/dist/esm/common/utils/isDev.mjs +2 -0
- package/dist/esm/common/utils/isDev.mjs.map +1 -0
- package/dist/esm/floor-plan.mjs +1 -0
- package/dist/esm/index.mjs +1 -1
- package/dist/esm/services/formValidation/FormValidatorGroupWithForm.mjs +1 -1
- package/dist/esm/services/formValidation/FormValidatorGroupWithForm.mjs.map +1 -1
- package/dist/floor-plan.cjs +1 -0
- package/dist/floorPlan-DLe5XAx6.cjs +2 -0
- package/dist/floorPlan-DLe5XAx6.cjs.map +1 -0
- package/dist/index.cjs +5 -3
- package/dist/index.cjs.map +1 -1
- package/dist/style.css +1 -1
- package/dist/types/common/accordion/accordion.types.d.ts +17 -2
- package/dist/types/common/actionButtons/actionButtons.types.d.ts +7 -1
- package/dist/types/common/actionIcon/actionIcon.d.ts +1 -1
- package/dist/types/common/actionIcon/actionIcon.types.d.ts +7 -9
- package/dist/types/common/alert/alert.types.d.ts +6 -8
- package/dist/types/common/animatedLogo/animatedLogo.types.d.ts +3 -2
- package/dist/types/common/badge/badge.types.d.ts +10 -6
- package/dist/types/common/button/button.types.d.ts +14 -4
- package/dist/types/common/calendar/calendar.types.d.ts +25 -10
- package/dist/types/common/calendar/components/agendaList/agendaList.d.ts +1 -1
- package/dist/types/common/calendar/components/agendaList/agendaList.types.d.ts +3 -0
- package/dist/types/common/calendar/components/calendarHeader/calendarHeader.d.ts +1 -1
- package/dist/types/common/calendar/components/calendarHeader/calendarHeader.types.d.ts +2 -0
- package/dist/types/common/calendar/components/compactMonth/compactMonth.d.ts +1 -1
- package/dist/types/common/calendar/components/monthView/monthView.d.ts +1 -1
- package/dist/types/common/calendar/components/monthView/monthView.types.d.ts +3 -2
- package/dist/types/common/calendar/components/timeGrid/timeGrid.d.ts +1 -1
- package/dist/types/common/calendar/components/timeGrid/timeGrid.types.d.ts +9 -1
- package/dist/types/common/calendar/dates.d.ts +21 -5
- package/dist/types/common/calendar/format.d.ts +3 -2
- package/dist/types/common/calendar/layout.d.ts +5 -0
- package/dist/types/common/calendar/useNow.d.ts +4 -0
- package/dist/types/common/calendar/view.types.d.ts +9 -2
- package/dist/types/common/card/card.types.d.ts +16 -2
- package/dist/types/common/chip/chip.types.d.ts +10 -5
- package/dist/types/common/copyButton/copyButton.types.d.ts +5 -4
- package/dist/types/common/fab/components/fabBase/fabBase.d.ts +1 -1
- package/dist/types/common/fab/components/fabBase/fabBase.types.d.ts +2 -1
- package/dist/types/common/floorPlan/floorPlan.graph.d.ts +10 -3
- package/dist/types/common/floorPlan/floorPlan.plan.d.ts +5 -0
- package/dist/types/common/floorPlan/floorPlan.rooms.d.ts +6 -2
- package/dist/types/common/floorPlan/floorPlan.snap.d.ts +1 -3
- package/dist/types/common/floorPlan/index.d.ts +1 -3
- package/dist/types/common/planCanvas/planCanvas.types.d.ts +1 -1
- package/dist/types/common/progressBar/progressBar.d.ts +0 -1
- package/dist/types/common/progressBar/progressBar.types.d.ts +3 -1
- package/dist/types/common/roomDrawer/roomDrawer.types.d.ts +29 -8
- package/dist/types/common/roomViewer/roomViewer.types.d.ts +4 -2
- package/dist/types/common/splitButton/splitButton.types.d.ts +4 -1
- package/dist/types/common/styles/tone.d.ts +11 -0
- package/dist/types/common/themeProvider/color.types.d.ts +20 -0
- package/dist/types/common/themeProvider/index.d.ts +2 -0
- package/dist/types/common/themeProvider/theme.types.d.ts +3 -6
- package/dist/types/common/timeline/timeline.types.d.ts +3 -10
- package/dist/types/common/toast/index.d.ts +1 -1
- package/dist/types/common/toast/toast.types.d.ts +7 -3
- package/dist/types/common/types/actions.types.d.ts +1 -1
- package/dist/types/common/utils/dismissClick.d.ts +4 -0
- package/dist/types/common/utils/isDev.d.ts +1 -0
- package/docs/Accordion.md +74 -5
- package/docs/ActionButtons.md +6 -3
- package/docs/ActionIcon.md +39 -14
- package/docs/Alert.md +27 -17
- package/docs/AnimatedLogo.md +1 -1
- package/docs/Badge.md +24 -7
- package/docs/Button.md +98 -40
- package/docs/ButtonGroup.md +18 -18
- package/docs/CLAUDE.md +24 -12
- package/docs/Calendar.md +35 -17
- package/docs/Card.md +53 -14
- package/docs/Chip.md +24 -9
- package/docs/ConfigProvider.md +3 -3
- package/docs/CopyButton.md +6 -5
- package/docs/FloorPlan.md +18 -14
- package/docs/ProgressBar.md +7 -4
- package/docs/RoomDrawer.md +42 -13
- package/docs/RoomViewer.md +1 -14
- package/docs/SectionHeader.md +1 -1
- package/docs/SplitButton.md +6 -5
- package/docs/ThemeColor.md +103 -0
- package/docs/ThemeProvider.md +5 -5
- package/docs/Timeline.md +18 -9
- package/docs/Toast.md +25 -11
- package/package.json +20 -2
- package/dist/cjs-types/common/floorPlan/legacySvg.d.ts +0 -27
- package/dist/esm/common/accordion/accordion.plain.module.mjs +0 -2
- package/dist/esm/common/accordion/accordion.plain.module.mjs.map +0 -1
- package/dist/esm/common/accordion/accordion.primary.module.mjs +0 -2
- package/dist/esm/common/accordion/accordion.primary.module.mjs.map +0 -1
- package/dist/esm/common/alert/alert.types.mjs +0 -2
- package/dist/esm/common/alert/alert.types.mjs.map +0 -1
- package/dist/esm/common/floorPlan/legacySvg.mjs +0 -2
- package/dist/esm/common/floorPlan/legacySvg.mjs.map +0 -1
- package/dist/types/common/floorPlan/legacySvg.d.ts +0 -27
package/docs/Calendar.md
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
# Calendar
|
|
2
2
|
|
|
3
|
-
**When to use:** Showing and editing your own events over time, in month, week, day and agenda views: bookings, shifts, appointments
|
|
3
|
+
**When to use:** Showing and editing your own events over time, in month, week, day and agenda views: bookings, shifts, appointments. To let a user pick one date, use [DatePicker](DatePicker.md); for a sequence of past steps, use [Timeline](Timeline.md).
|
|
4
4
|
|
|
5
|
-
**Keywords:** schedule, scheduler, planner, appointments, booking, meetings, week view, month view, drag and drop, events
|
|
5
|
+
**Keywords:** schedule, scheduler, planner, appointments, booking, meetings, week view, month view, drag and drop, events, business hours, opening hours, calendar week, KW
|
|
6
6
|
|
|
7
7
|
**Import:** `import { Calendar, CalendarView } from '@ahrowe/ui'`
|
|
8
8
|
**Types:** `import type { CalendarProps, CalendarEvent, CalendarRange, CalendarEventChange, CalendarEventContext, CalendarSlot, CalendarLabels, CalendarWeekday, CalendarWeekStart, CalendarSlots, CalendarDefaults } from '@ahrowe/ui'`
|
|
@@ -49,8 +49,8 @@ const [editing, setEditing] = useState<{ booking: Booking | CalendarSlot; anchor
|
|
|
49
49
|
// Read-only month and agenda
|
|
50
50
|
<Calendar events={events} views={[CalendarView.Month, CalendarView.Agenda]} />
|
|
51
51
|
|
|
52
|
-
// A working week
|
|
53
|
-
<Calendar events={events} defaultView={CalendarView.Week} hiddenDays={[0, 6]}
|
|
52
|
+
// A working week, 08:00 to 17:00, with the rest of the day shaded
|
|
53
|
+
<Calendar events={events} defaultView={CalendarView.Week} hiddenDays={[0, 6]} workingHours={[8, 17]} />
|
|
54
54
|
```
|
|
55
55
|
|
|
56
56
|
**Enums:** `CalendarView`: `Month`, `Week`, `Day`, `Agenda`
|
|
@@ -59,28 +59,38 @@ const [editing, setEditing] = useState<{ booking: Booking | CalendarSlot; anchor
|
|
|
59
59
|
|
|
60
60
|
**Events** are plain objects: `{ id, title, start, end, allDay?, color?, readOnly? }`.
|
|
61
61
|
|
|
62
|
+
- `id` is **unique among `events`**. Each occurrence of a recurring series needs its own, such as `` `${seriesId}-${day}` ``: two events with one id are drawn with one React key, and a drag picks up the first of them.
|
|
62
63
|
- `end` is **exclusive**, for timed and all-day events alike. A one-day all-day event on the 26th runs from midnight on the 26th to midnight on the 27th. A timed event ending at midnight does not show on the next day.
|
|
63
64
|
- Timed events of 24 hours or more are drawn in the all-day row, not stretched down the time grid.
|
|
64
65
|
- A timed event is drawn exactly as long as it lasts. One under 15 minutes has no room for its title, so it is a bar of its real length with the title on a line beneath it, and the next event in its column leaves that line free. Zoomed in far enough, the bar holds its title like any other event.
|
|
65
|
-
- `color` is any CSS colour,
|
|
66
|
+
- `color` is a `ThemeColor` (`color: ThemeColor.Success`) or any CSS colour, see [ThemeColor.md](ThemeColor.md). The event is tinted from it against the page background, so any colour reads in both light and dark themes.
|
|
66
67
|
- `readOnly` events can still be clicked, but not moved or resized.
|
|
67
68
|
|
|
68
69
|
**Loading events and recurring series.** `onRangeChange` fires on mount and whenever the shown period changes, with that period **and one either side of it**, because swiping reveals the neighbours before it pages. Fetch events for that range, and expand recurring series into it yourself: the calendar has no recurrence rules of its own.
|
|
69
70
|
|
|
70
71
|
```tsx
|
|
71
72
|
const [events, setEvents] = useState<CalendarEvent[]>([]);
|
|
73
|
+
const latest = useRef<CalendarRange | null>(null);
|
|
72
74
|
|
|
73
75
|
<Calendar
|
|
74
76
|
events={events}
|
|
75
|
-
onRangeChange={async (
|
|
77
|
+
onRangeChange={async (range) => {
|
|
78
|
+
latest.current = range;
|
|
79
|
+
const loaded = await api.events(range.start, range.end);
|
|
80
|
+
// Paged on while this loaded: a later range's answer is the one to show.
|
|
81
|
+
if (latest.current === range) setEvents(loaded);
|
|
82
|
+
}}
|
|
76
83
|
/>
|
|
77
84
|
```
|
|
78
85
|
|
|
79
86
|
**Editing:**
|
|
80
87
|
|
|
81
|
-
- With a **mouse**, drag on empty time to create, drag an event to move it, and drag its bottom edge to resize it. A plain click on empty time creates an hour (or `slotMinutes`, if longer)
|
|
88
|
+
- With a **mouse**, drag on empty time to create, drag an event to move it, and drag its bottom edge to resize it. A plain click on empty time creates an hour (or `slotMinutes`, if longer).
|
|
89
|
+
- **Whole days** are created and moved the same way in the month view and in the all-day row of the week and day views: a click creates an all-day slot on that day, a drag across days creates one over all of them, and dragging an event moves it by days.
|
|
82
90
|
- With **touch**, press and hold for 400ms to pick up, then drag. A tap does what a click does. On a coarse pointer the resize grip is always visible.
|
|
83
91
|
- Moving and resizing snap to `slotMinutes`. A live time label follows the drag, and `Escape` cancels it.
|
|
92
|
+
- The header's **New event** button (shown when `onSlotCreate` is set) creates on the selected day: in the week and day views the hour from the next full hour of the clock (23:00 at the latest, so it stays on that day), elsewhere the whole day. It is the keyboard's way to create.
|
|
93
|
+
- A click on empty time that closes a `Popover` of this library, such as your editor, only closes it; the next click creates. A click on another event still opens that one.
|
|
84
94
|
- Update `events` in the same render as `onEventChange`, or **return a promise**: the event then stays where it was dropped until the promise settles, and is drawn from `events` again after that. So update `events` before it resolves, and reject to put the event back:
|
|
85
95
|
|
|
86
96
|
```tsx
|
|
@@ -123,7 +133,11 @@ The example also:
|
|
|
123
133
|
|
|
124
134
|
**Navigating:** the header's arrows, **Today** and the view switcher. In the month, week and day views a horizontal swipe on touch pages to the next or previous period, with its events already in view while you swipe; the agenda is a list and pages with the arrows only. Pinch the week or day view, or hold Ctrl and use the wheel or trackpad, to zoom the hours; the zoom is kept when switching views. Clicking a day number, or a weekday in the week view, opens that day.
|
|
125
135
|
|
|
126
|
-
**On a narrow calendar** (under 600px of its own width, not the viewport's) the month view becomes a grid with coloured dots above the selected day's events. Tapping a day selects it rather than opening it
|
|
136
|
+
**On a narrow calendar** (under 600px of its own width, not the viewport's) the month view becomes a grid with coloured dots above the selected day's events. Tapping a day selects it rather than opening it; the header's **New event** button creates an all-day slot on it. Scrolling the list folds the month up into the selected week; swiping then pages by week instead of by month. Under `prefers-reduced-motion: reduce` the month folds in one step, once the list has scrolled the whole way, instead of following the scroll.
|
|
137
|
+
|
|
138
|
+
The week view of a narrow calendar shows **three days** from the selected one and pages by three, as seven columns at phone width leave no room for a title. The switcher still calls it Week, and `onRangeChange` reports those three days and their neighbours.
|
|
139
|
+
|
|
140
|
+
**Working hours and week numbers:** `workingHours={[8, 17]}` shades the hours before 08:00 and from 17:00 in the week and day views, and makes 08:00 the hour they open at when today is not shown. `[22, 6]` is an overnight shift, shaded from 06:00 to 22:00. `showWeekNumbers` labels each row of the month view and the corner of the week and day views with its **ISO 8601** week, the numbering used across most of Europe; a week that starts on another day than Monday shows the ISO week holding most of its days. The month of a narrow calendar has no room for them and leaves them out. `labels.weekNumber` words it: ``(week) => `KW ${week}` `` in German.
|
|
127
141
|
|
|
128
142
|
**Key props:**
|
|
129
143
|
|
|
@@ -131,30 +145,33 @@ The example also:
|
|
|
131
145
|
|------|------|-------------|
|
|
132
146
|
| `events` | `E[]` | The events to show, `E extends CalendarEvent` |
|
|
133
147
|
| `date` / `defaultDate` / `onDateChange` | `string` | Selected day, `'YYYY-MM-DD'`, controlled or uncontrolled: the same value a [DatePicker](DatePicker.md) holds, so the two can share state |
|
|
134
|
-
| `view` / `defaultView` / `onViewChange` | `CalendarView` | Shown view, controlled or uncontrolled (default `
|
|
148
|
+
| `view` / `defaultView` / `onViewChange` | `CalendarView` | Shown view, controlled or uncontrolled (default the first of `views`) |
|
|
135
149
|
| `views` | `CalendarView[]` | Views in the switcher, in order; hidden when there is one (default all four) |
|
|
136
150
|
| `locale` | `string` | BCP 47 tag for dates, times and the week start (default the browser's) |
|
|
137
151
|
| `weekStartsOn` | `0` to `6` | First day of the week, `0` being Sunday (default the locale's, else Monday) |
|
|
138
152
|
| `slotMinutes` | `number` | What creating, moving and resizing snap to (default `15`) |
|
|
139
153
|
| `hiddenDays` | `CalendarWeekday[]` | Weekdays left out of every view, `0` being Sunday: `[0, 6]` hides the weekend |
|
|
140
|
-
| `scrollToHour` | `number` | Hour the week and day views open at, such as `6` (default an hour before now while today is shown, otherwise `7`) |
|
|
154
|
+
| `scrollToHour` | `number` | Hour the week and day views open at, such as `6` (default an hour before now while today is shown, otherwise the start of `workingHours`, or `7`) |
|
|
155
|
+
| `workingHours` | `[start, end]` | Hours of working time in the week and day views, `[8, 17]`, or `[22, 6]` overnight; the rest is shaded |
|
|
156
|
+
| `showWeekNumbers` | `boolean` | ISO 8601 week numbers on the month's rows and in the week and day views' corner (default `false`) |
|
|
141
157
|
| `onRangeChange` | `(range: CalendarRange) => void` | The shown period plus one on either side |
|
|
142
158
|
| `onEventClick` | `(event: E, anchor: HTMLElement) => void` | An event was clicked; `anchor` is its element, ready for `Popover`'s `anchor` |
|
|
143
159
|
| `onEventChange` | `(change: CalendarEventChange<E>) => void \| Promise<unknown>` | Moved or resized. Setting it makes events draggable. A returned promise keeps the event in place until it settles |
|
|
144
|
-
| `onSlotCreate` | `(slot: CalendarSlot, anchor: HTMLElement) => void` | Empty time clicked or dragged over. Setting it enables creating. `anchor` is the day's cell in the month view
|
|
160
|
+
| `onSlotCreate` | `(slot: CalendarSlot, anchor: HTMLElement) => void` | Empty time clicked or dragged over, or the header's **New event** pressed. Setting it enables creating. `anchor` is ready for `Popover`'s `anchor`: the first day's cell in the month view, the first day's header for the all-day row, an invisible box over the new slot in the time grid, and the button itself from the header |
|
|
145
161
|
| `renderEvent` | `(event: E, context: CalendarEventContext) => ReactNode` | Content of an event in place of its title. No interactive elements. `context.singleLine` is set where it has one line: an event under 45 minutes, an all-day bar, a month row. Keep to the title there |
|
|
162
|
+
| `eventClassName` | `(event: E) => string \| undefined` | A class for one event's element in every view, next to `classNames.event`: a tentative, cancelled or selected event |
|
|
146
163
|
| `ref` | `Ref<HTMLDivElement>` | The root element |
|
|
147
164
|
|
|
148
165
|
Give the calendar a height. It is `40em` tall by default and scrolls inside itself; `style={{ height: '100dvh' }}` or a class sets another.
|
|
149
166
|
|
|
150
|
-
**Keyboard:** in the month view the days are a grid with one tab stop on the selected day: `←`/`→` move a day, `↑`/`↓` a week, `Home`/`End` go to the start and end of the week, `PageUp`/`PageDown` a month. `Enter` or `Space` opens a list of that day's events, with a **New event** button when `onSlotCreate` is set. In the week and day views every event is a button, in time order.
|
|
167
|
+
**Keyboard:** in the month view the days are a grid with one tab stop on the selected day: `←`/`→` move a day, `↑`/`↓` a week, `Home`/`End` go to the start and end of the week, `PageUp`/`PageDown` a month. `Enter` or `Space` opens a list of that day's events, with a **New event** button when `onSlotCreate` is set. In the week and day views every event is a button, in time order. The header's **New event** button creates in every view; opened from it with the keyboard, a `Popover` editor takes the focus.
|
|
151
168
|
|
|
152
169
|
**Accessibility:**
|
|
153
170
|
|
|
154
171
|
- The period title is a polite live region, so paging is announced.
|
|
155
172
|
- Days carry their full date and event count as their name, and today has `aria-current="date"`.
|
|
156
173
|
- Each day column of the time grid is a group named by its date.
|
|
157
|
-
- **Dragging needs a single-pointer alternative (WCAG 2.5.7).** Creating has one, a click. For moving and resizing it has to be your `onEventClick` dialog, so let it edit the start and end.
|
|
174
|
+
- **Dragging needs a single-pointer alternative (WCAG 2.5.7).** Creating has one, a click, and the header's button. For moving and resizing it has to be your `onEventClick` dialog, so let it edit the start and end.
|
|
158
175
|
|
|
159
176
|
**Theming:** these are theme variables (typed on `ThemeVariables`). Set them theme-wide via `ThemeProvider`'s `variables`, or per instance via `style`:
|
|
160
177
|
|
|
@@ -164,21 +181,22 @@ Give the calendar a height. It is `40em` tall by default and scrolls inside itse
|
|
|
164
181
|
| `--calendar-today-color` | `var(--primary-color)` |
|
|
165
182
|
| `--calendar-now-color` | `var(--error-color)` |
|
|
166
183
|
| `--calendar-event-radius` | `6px` |
|
|
184
|
+
| `--calendar-off-hours-color` | `var(--background-accent)` (the hours outside `workingHours`) |
|
|
167
185
|
|
|
168
|
-
**Global defaults:** `ConfigProvider` sets `labels`, `locale`, `weekStartsOn`, `slotMinutes`, `views`, `hiddenDays` and `
|
|
186
|
+
**Global defaults:** `ConfigProvider` sets `labels`, `locale`, `weekStartsOn`, `slotMinutes`, `views`, `hiddenDays`, `scrollToHour`, `workingHours` and `showWeekNumbers` for every calendar, e.g. `defaultProps={{ Calendar: { locale: 'de-AT', weekStartsOn: 1 } }}`. The other props depend on your event type, so they are set per instance. See [ConfigProvider.md](ConfigProvider.md).
|
|
169
187
|
|
|
170
188
|
**Slots:** `root` `header` `dayHeader` `cell` `event`
|
|
171
189
|
|
|
172
|
-
**Labels:** `previous` `next` `today` `viewSwitcher` `month` `week` `day` `agenda` `allDay` `more` `eventCount` `noEvents` `newEvent`: the text this component renders of its own. `more` and `eventCount` are functions of a count. Dates and times come from `locale`, not from here. Pass `labels` to override any of them, on the component or app-wide through `ConfigProvider`; keys merge individually. Type: `CalendarLabels`.
|
|
190
|
+
**Labels:** `previous` `next` `today` `viewSwitcher` `month` `week` `day` `agenda` `allDay` `more` `eventCount` `noEvents` `newEvent` `weekNumber`: the text this component renders of its own. `more` and `eventCount` are functions of a count, `weekNumber` of the week's number. Dates and times come from `locale`, not from here. Pass `labels` to override any of them, on the component or app-wide through `ConfigProvider`; keys merge individually. Type: `CalendarLabels`.
|
|
173
191
|
|
|
174
192
|
**Limits:**
|
|
175
193
|
|
|
176
|
-
- **One time zone, the browser's.**
|
|
194
|
+
- **One time zone, the browser's.** Every day boundary and clock time is worked out from the local `Date` fields. Showing another zone would mean routing each of them through `Intl` offset lookups, which the calendar does not do.
|
|
177
195
|
- **No recurrence rules.** Expand series for the range `onRangeChange` reports.
|
|
178
196
|
- **Moving stays within the shown period**, and between days or times of the same kind: an event cannot be dragged from the time grid into the all-day row.
|
|
197
|
+
- **No resource columns.** A column per person or room, as a team schedule has, is not a view of its own.
|
|
179
198
|
- **No right-to-left layout.**
|
|
180
199
|
- **Safari on macOS** sends a trackpad pinch as a gesture event rather than a Ctrl+wheel, so there it zooms the page as usual; pinching on a touch screen zooms the hours in every browser.
|
|
181
200
|
- **A controlled `date` must update in the same render as `onDateChange`.** After a swipe, the calendar shows the new period's panes straight away; a parent that updates later makes it jump back and forth.
|
|
182
|
-
- **A tap outside your own popover also reaches the calendar.** `Popover` closes on pointer release and lets the click through, so a tap on empty time closes it and creates a slot: an editor opened from `onSlotCreate` moves to the new slot.
|
|
183
201
|
|
|
184
202
|
HTML attributes such as `id`, `aria-label` and `data-*` are passed to the root element.
|
package/docs/Card.md
CHANGED
|
@@ -4,26 +4,46 @@
|
|
|
4
4
|
|
|
5
5
|
**Keywords:** panel, box
|
|
6
6
|
|
|
7
|
-
**Import:** `import { Card, CardStyleType, CardHeader, CardMedia, CardContent, CardActions } from '@ahrowe/ui'`
|
|
7
|
+
**Import:** `import { Card, CardStyleType, CardHeader, CardMedia, CardContent, CardActions, ThemeColor } from '@ahrowe/ui'`
|
|
8
8
|
|
|
9
|
-
**
|
|
9
|
+
**Styles:** `Outlined` and `Light` mean what they mean on Button, Badge and Chip; `color` is the
|
|
10
|
+
colour they use (a `ThemeColor`, default `Neutral`, or any CSS colour, see
|
|
11
|
+
[ThemeColor.md](ThemeColor.md)). Text inside stays the page's text colour in every style. There
|
|
12
|
+
is no `Filled`: body text on a solid colour reads badly.
|
|
13
|
+
|
|
14
|
+
- `CardStyleType.Elevated` (default): a raised surface with a shadow, always neutral
|
|
15
|
+
- `CardStyleType.Outlined`: a border in the colour, no fill. In a colour it marks one card among its neighbours, such as the current plan. Say what the mark means in text as well (a subtitle or a Badge): the colour alone is not read out
|
|
16
|
+
- `CardStyleType.Light`: a flat tint of the colour, no border. In a colour it sets one card apart by a colour of its own, such as the recommended plan or a category
|
|
17
|
+
|
|
18
|
+
A message about something that happened (saved, failed, almost full) is not a coloured card but an
|
|
19
|
+
[Alert](Alert.md), which brings the icon, the screen-reader role and the dismiss button.
|
|
10
20
|
|
|
11
21
|
```tsx
|
|
12
|
-
import { Card, CardStyleType, CardHeader, CardMedia, CardContent, CardActions } from '@ahrowe/ui';
|
|
22
|
+
import { Card, CardStyleType, CardHeader, CardMedia, CardContent, CardActions, ThemeColor } from '@ahrowe/ui';
|
|
13
23
|
|
|
14
|
-
// Elevated (default)
|
|
24
|
+
// Elevated (default): fill and shadow
|
|
15
25
|
<Card>
|
|
16
|
-
<CardHeader title="Elevated" subTitle="Fill
|
|
26
|
+
<CardHeader title="Elevated" subTitle="Fill and shadow" />
|
|
17
27
|
</Card>
|
|
18
28
|
|
|
19
|
-
// Outlined
|
|
29
|
+
// Outlined: transparent, defined by a border, no shadow
|
|
20
30
|
<Card styleType={CardStyleType.Outlined}>
|
|
21
31
|
<CardHeader title="Outlined" />
|
|
22
32
|
</Card>
|
|
23
33
|
|
|
24
|
-
//
|
|
25
|
-
<Card styleType={CardStyleType.
|
|
26
|
-
<CardHeader title="
|
|
34
|
+
// Light: flat fill, no shadow
|
|
35
|
+
<Card styleType={CardStyleType.Light}>
|
|
36
|
+
<CardHeader title="Light" />
|
|
37
|
+
</Card>
|
|
38
|
+
|
|
39
|
+
// The selected plan, bordered in the primary colour
|
|
40
|
+
<Card styleType={CardStyleType.Outlined} color={ThemeColor.Primary}>
|
|
41
|
+
<CardHeader title="Pro" subTitle="Your current plan" />
|
|
42
|
+
</Card>
|
|
43
|
+
|
|
44
|
+
// The recommended plan, tinted
|
|
45
|
+
<Card styleType={CardStyleType.Light} color={ThemeColor.Primary}>
|
|
46
|
+
<CardHeader title="Team" subTitle="Recommended for 5 people or more" />
|
|
27
47
|
</Card>
|
|
28
48
|
|
|
29
49
|
<Card hoverEffect onClick={handleClick}>
|
|
@@ -39,7 +59,7 @@ import { Card, CardStyleType, CardHeader, CardMedia, CardContent, CardActions }
|
|
|
39
59
|
<CardActions
|
|
40
60
|
actions={[
|
|
41
61
|
{ id: 'edit', label: 'Edit', onClick: handleEdit },
|
|
42
|
-
{ id: 'delete', label: 'Delete',
|
|
62
|
+
{ id: 'delete', label: 'Delete', color: ThemeColor.Error, onClick: handleDelete },
|
|
43
63
|
]}
|
|
44
64
|
/>
|
|
45
65
|
</Card>
|
|
@@ -49,15 +69,16 @@ All sub-components are optional — use only what you need. Stacked sub-componen
|
|
|
49
69
|
|
|
50
70
|
**Enums:**
|
|
51
71
|
|
|
52
|
-
- `CardStyleType`: `Elevated` (default) | `Outlined` | `
|
|
72
|
+
- `CardStyleType`: `Elevated` (default) | `Outlined` | `Light`
|
|
53
73
|
|
|
54
74
|
**CardProps:**
|
|
55
75
|
|
|
56
76
|
| Prop | Type | Description |
|
|
57
77
|
|------|------|-------------|
|
|
58
|
-
| `styleType` | `CardStyleType` |
|
|
78
|
+
| `styleType` | `CardStyleType` | `Elevated` (default, fill and shadow), `Outlined` (a border) or `Light` (a flat fill) |
|
|
79
|
+
| `color` | `ColorValue` | The border of `Outlined` and the tint of `Light`: a `ThemeColor` (default `Neutral`, the theme's card surfaces) or any CSS colour. `Elevated` ignores it |
|
|
59
80
|
| `onClick` | `() => void` | Makes the card clickable, by pointer and by Enter/Space. A click or key on a control inside the card (a field, a link, a button, anything with an interactive `role`) is that control's, and neither fires this nor ripples |
|
|
60
|
-
| `hoverEffect` | `boolean` |
|
|
81
|
+
| `hoverEffect` | `boolean` | Lifts the card on hover and tints it in its text colour, over whatever its style and colour paint |
|
|
61
82
|
| `tabIndex` | `number \| null` | For keyboard navigation |
|
|
62
83
|
| `autoGap` | `boolean` | Space stacked sub-components apart with a shared gap (default `true`); set `false` to space them yourself |
|
|
63
84
|
| `clip` | `boolean` | Clip content to the rounded corners (`overflow: hidden`, default `false`). Set `true` for full-bleed `CardMedia` or a clipped hover/ripple effect. Safe to enable even when the card holds a `Dropdown`/`Popover`/`Tooltip` — those popovers are portaled and always escape the card regardless of this setting |
|
|
@@ -75,7 +96,7 @@ All sub-components are optional — use only what you need. Stacked sub-componen
|
|
|
75
96
|
|
|
76
97
|
| Prop | Type | Description |
|
|
77
98
|
|------|------|-------------|
|
|
78
|
-
| `actions` | `CardAction[]` | Array of `{ id, label, styleType, onClick }` renders Buttons |
|
|
99
|
+
| `actions` | `CardAction[]` | Array of `{ id, label, styleType, color, onClick }` renders Buttons (`Outlined` `Primary` unless set) |
|
|
79
100
|
| `children` | `ReactNode` | Custom content instead of `actions` |
|
|
80
101
|
|
|
81
102
|
## Sizing
|
|
@@ -85,3 +106,21 @@ Card is spaced by its font: the padding, the header's gap and thumbnail, the gap
|
|
|
85
106
|
`CardMedia` bleeds to the card's edges with a negative margin that has to stay equal to the padding, so change the two together.
|
|
86
107
|
|
|
87
108
|
**Slots:** `root` `content`
|
|
109
|
+
|
|
110
|
+
## Migration from `Filled`
|
|
111
|
+
|
|
112
|
+
Before 0.43 the flat style was called `Filled`. It is `Light` now, the name the library's other
|
|
113
|
+
components use for the same look. TypeScript points at each use:
|
|
114
|
+
|
|
115
|
+
| Before | After |
|
|
116
|
+
|--------|-------|
|
|
117
|
+
| `styleType={CardStyleType.Filled}` | `styleType={CardStyleType.Light}` |
|
|
118
|
+
|
|
119
|
+
`defaultTheme` and `lightTheme` still draw it in `Neutral` in `--background-accent`, through
|
|
120
|
+
`--background-card-filled`. A theme that does not set that variable now gets the see-through tint
|
|
121
|
+
of the text colour that every other `Light` uses, where it used to get `--background-accent`. On a
|
|
122
|
+
dark theme that tint is about as light as `Elevated`, so set the variable there to keep the two
|
|
123
|
+
apart.
|
|
124
|
+
|
|
125
|
+
A card with `hoverEffect` no longer turns `--background-accent` on hover: it keeps its own surface
|
|
126
|
+
and gets a light tint in its text colour over it, so a coloured card keeps its colour.
|
package/docs/Chip.md
CHANGED
|
@@ -4,20 +4,22 @@
|
|
|
4
4
|
|
|
5
5
|
**Keywords:** pill
|
|
6
6
|
|
|
7
|
-
**Import:** `import { Chip, ChipContainer, ChipStyleType } from '@ahrowe/ui'`
|
|
7
|
+
**Import:** `import { Chip, ChipContainer, ChipStyleType, ThemeColor } from '@ahrowe/ui'`
|
|
8
8
|
|
|
9
|
-
**
|
|
9
|
+
**Styles:** `ChipStyleType.Light` (default) | `ChipStyleType.Filled` | `ChipStyleType.Outlined`, in any `color`: a `ThemeColor` (default `Neutral`) or any CSS colour, see [ThemeColor.md](ThemeColor.md).
|
|
10
10
|
|
|
11
11
|
```tsx
|
|
12
|
-
import { Chip, ChipContainer, ChipStyleType } from '@ahrowe/ui';
|
|
12
|
+
import { Chip, ChipContainer, ChipStyleType, ThemeColor } from '@ahrowe/ui';
|
|
13
13
|
|
|
14
14
|
// Basic chip
|
|
15
15
|
<Chip text="React" />
|
|
16
16
|
|
|
17
|
-
//
|
|
18
|
-
<Chip text="
|
|
19
|
-
<Chip text="
|
|
20
|
-
|
|
17
|
+
// Colours: a light tint by default
|
|
18
|
+
<Chip text="Warning" color={ThemeColor.Warn} />
|
|
19
|
+
<Chip text="Error" color={ThemeColor.Error} />
|
|
20
|
+
|
|
21
|
+
// A selected filter: filled in the primary colour
|
|
22
|
+
<Chip text="Active" styleType={ChipStyleType.Filled} color={ThemeColor.Primary} onClick={toggle} />
|
|
21
23
|
|
|
22
24
|
// Removable chip
|
|
23
25
|
<Chip
|
|
@@ -47,14 +49,15 @@ import { Chip, ChipContainer, ChipStyleType } from '@ahrowe/ui';
|
|
|
47
49
|
|
|
48
50
|
**Enums:**
|
|
49
51
|
|
|
50
|
-
- `ChipStyleType`: `
|
|
52
|
+
- `ChipStyleType`: `Light` (default) | `Filled` | `Outlined`
|
|
51
53
|
|
|
52
54
|
**ChipProps:**
|
|
53
55
|
|
|
54
56
|
| Prop | Type | Description |
|
|
55
57
|
|------|------|-------------|
|
|
56
58
|
| `text` | `string` | Chip label |
|
|
57
|
-
| `styleType` | `ChipStyleType` |
|
|
59
|
+
| `styleType` | `ChipStyleType` | `Light` (default), `Filled` or `Outlined` |
|
|
60
|
+
| `color` | `ColorValue` | A `ThemeColor` (default `Neutral`) or any CSS colour |
|
|
58
61
|
| `thumbnail` | `string` | Avatar image URL |
|
|
59
62
|
| `labels.remove` | `string` | Accessible name for the remove button. Default: `'Remove'` |
|
|
60
63
|
| `showRemoveIcon` | `boolean` | Show × icon |
|
|
@@ -70,3 +73,15 @@ import { Chip, ChipContainer, ChipStyleType } from '@ahrowe/ui';
|
|
|
70
73
|
**Labels:** `remove` — the text this component renders of its own. Pass `labels` to override any of them, on the component or app-wide through `ConfigProvider`; keys merge individually. Type: `ChipLabels`.
|
|
71
74
|
|
|
72
75
|
**Slots:** `root` `inner` `thumbnail` `text` `removeIcon`
|
|
76
|
+
|
|
77
|
+
## Migration from colour styles
|
|
78
|
+
|
|
79
|
+
Before 0.43, `ChipStyleType` was a colour, and `Primary` was filled while the others were a light
|
|
80
|
+
tint. Style and colour are now separate props. The old members are gone and TypeScript points at
|
|
81
|
+
each:
|
|
82
|
+
|
|
83
|
+
| Before | After |
|
|
84
|
+
|--------|-------|
|
|
85
|
+
| `styleType={ChipStyleType.Default}` | nothing: `Light` `Neutral` is the default |
|
|
86
|
+
| `styleType={ChipStyleType.Primary}` | `styleType={ChipStyleType.Filled} color={ThemeColor.Primary}` |
|
|
87
|
+
| `styleType={ChipStyleType.Info}` (and `Warn`, `Error`) | `color={ThemeColor.Info}` |
|
package/docs/ConfigProvider.md
CHANGED
|
@@ -98,7 +98,7 @@ Each entry is a `Partial<...Props>`, so any of that component's props can be def
|
|
|
98
98
|
- **Display:** `Button` · `CopyButton` · `ActionButtons` · `Badge` · `Chip` · `Card` · `SectionHeader` · `Skeleton` · `Accordion` · `Divider` · `Timer` · `WeatherIcon`
|
|
99
99
|
- **Overlays:** `ConfirmModal` · `Modal` · `CommandPalette` · `Popover`
|
|
100
100
|
- **Editors:** `RoomDrawer`, `RoomViewer`
|
|
101
|
-
- **Scheduling:** `Calendar`, for `labels`, `locale`, `weekStartsOn`, `slotMinutes`, `views`, `hiddenDays` and `
|
|
101
|
+
- **Scheduling:** `Calendar`, for `labels`, `locale`, `weekStartsOn`, `slotMinutes`, `views`, `hiddenDays`, `scrollToHour`, `workingHours` and `showWeekNumbers` only (see below)
|
|
102
102
|
|
|
103
103
|
```tsx
|
|
104
104
|
<ConfigProvider
|
|
@@ -106,7 +106,7 @@ Each entry is a `Partial<...Props>`, so any of that component's props can be def
|
|
|
106
106
|
Input: { alwaysFloatLabel: true },
|
|
107
107
|
Dropdown: { useMatLabelStyle: true },
|
|
108
108
|
NumberInput: { decimalScale: 2, thousandSeparator: '.' },
|
|
109
|
-
Button: { styleType: ButtonStyleType.
|
|
109
|
+
Button: { styleType: ButtonStyleType.Filled },
|
|
110
110
|
Card: { styleType: CardStyleType.Outlined },
|
|
111
111
|
Skeleton: { animation: SkeletonAnimation.Pulse },
|
|
112
112
|
}}
|
|
@@ -138,6 +138,6 @@ Every string a component renders of its own is set through its `labels` prop, an
|
|
|
138
138
|
|
|
139
139
|
**Labels merge per key**, unlike every other default here. An instance that overrides one string keeps the provider's translations for the rest, so `<Alert labels={{ dismiss: 'Weg damit' }} />` under the provider above does not lose anything else Alert might have been given. Anything the component does not produce itself, a `title`, a column `label`, a button's children, is already yours and never appears in `labels`.
|
|
140
140
|
|
|
141
|
-
`ColorPicker` and `VirtualList` appear in `ComponentDefaults` with their labels only: the first is configured elsewhere, the second has generic props that a per-key default map cannot express. `Calendar` is generic too, so its entry is the props that do not depend on the event type: `labels`, `locale`, `weekStartsOn`, `slotMinutes`, `views`, `hiddenDays` and `
|
|
141
|
+
`ColorPicker` and `VirtualList` appear in `ComponentDefaults` with their labels only: the first is configured elsewhere, the second has generic props that a per-key default map cannot express. `Calendar` is generic too, so its entry is the props that do not depend on the event type: `labels`, `locale`, `weekStartsOn`, `slotMinutes`, `views`, `hiddenDays`, `scrollToHour`, `workingHours` and `showWeekNumbers`. `Toast` is not there at all, because `AhroweProvider`'s `toast` prop is already its app-wide configuration and carries `labels` itself.
|
|
142
142
|
|
|
143
143
|
Each component's doc lists its own keys under **Labels:**.
|
package/docs/CopyButton.md
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
**Types:** `import type { CopyButtonProps, CopyButtonLabels } from '@ahrowe/ui'`
|
|
9
9
|
|
|
10
10
|
```tsx
|
|
11
|
-
import { CopyButton, Input } from '@ahrowe/ui';
|
|
11
|
+
import { CopyButton, Input, ThemeColor, showToast } from '@ahrowe/ui';
|
|
12
12
|
|
|
13
13
|
<span>
|
|
14
14
|
{invoice.number} <CopyButton value={invoice.number} />
|
|
@@ -18,10 +18,10 @@ import { CopyButton, Input } from '@ahrowe/ui';
|
|
|
18
18
|
<Input label='API key' value={apiKey} readOnly suffix={<CopyButton value={apiKey} />} />
|
|
19
19
|
|
|
20
20
|
// a toast on success, where the button is not where the user is looking
|
|
21
|
-
<CopyButton value={url} onCopy={() => showToast('Link copied', {
|
|
21
|
+
<CopyButton value={url} onCopy={() => showToast('Link copied', { color: ThemeColor.Success })} />
|
|
22
22
|
```
|
|
23
23
|
|
|
24
|
-
After a click the icon rotates into a check (through `AnimatedIcon`, held still under `prefers-reduced-motion`) for `timeout` ms, the accessible name and tooltip read "Copied", and a polite live region announces it, because a swapped icon or a changed `aria-label` alone is not read out. A refused write (an insecure context, a blocked iframe) announces "Could not copy" and calls `onError`; the icon stays as it was. `CopyButton` shows no toast of its own: pass one through `onCopy` / `onError` if you want it.
|
|
24
|
+
It is an [ActionIcon](ActionIcon.md), so it takes the same `styleType` and `color`, and turns `Success` while copied. After a click the icon rotates into a check (through `AnimatedIcon`, held still under `prefers-reduced-motion`) for `timeout` ms, the accessible name and tooltip read "Copied", and a polite live region announces it, because a swapped icon or a changed `aria-label` alone is not read out. A refused write (an insecure context, a blocked iframe) announces "Could not copy" and calls `onError`; the icon stays as it was. `CopyButton` shows no toast of its own: pass one through `onCopy` / `onError` if you want it.
|
|
25
25
|
|
|
26
26
|
The live region is rendered as a sibling of the button, so `CopyButton` returns two elements. It is visually hidden and takes no space.
|
|
27
27
|
|
|
@@ -35,8 +35,9 @@ The live region is rendered as a sibling of the button, so `CopyButton` returns
|
|
|
35
35
|
| `copiedIcon` | `IconDefinition \| ReactElement` | Icon while copied (default `faCheck`) |
|
|
36
36
|
| `onCopy` | `(value: string) => void` | Called after a successful copy |
|
|
37
37
|
| `onError` | `() => void` | Called when the clipboard refuses the write. `useClipboard` returns the reason |
|
|
38
|
-
| `onClick` | `(event: MouseEvent) => void` | Called on every click, before the copy |
|
|
39
|
-
| `
|
|
38
|
+
| `onClick` | `(event: MouseEvent<HTMLButtonElement>) => void` | Called on every click, before the copy |
|
|
39
|
+
| `color` | `ColorValue` | Its colour at rest (default `Neutral`); `Success` while copied |
|
|
40
|
+
| `ref` | `Ref<HTMLButtonElement>` | Ref to the button |
|
|
40
41
|
|
|
41
42
|
**Global defaults:** adopts `ConfigProvider`, e.g. `defaultProps={{ CopyButton: { timeout: 1500 } }}`. See [ConfigProvider.md](ConfigProvider.md).
|
|
42
43
|
|
package/docs/FloorPlan.md
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
**Keywords:** blueprint, cad, grundriss, apartment, building, storey, partition, area calculation, planar graph, half-edge, extrusion
|
|
6
6
|
|
|
7
|
-
**Import:** `import { emptyFloorPlan, addWall, derivePlan } from '@ahrowe/ui'`
|
|
7
|
+
**Import:** `import { emptyFloorPlan, addWall, derivePlan } from '@ahrowe/ui'`, or from `'@ahrowe/ui/floor-plan'` where there is no React
|
|
8
8
|
**Types:** `import type { FloorPlan, PlanFloor, PlanNode, PlanWall, PlanOpening, PlanRoom, DerivedRoom, PlanPoint, PlanView, PlanSelection } from '@ahrowe/ui'`
|
|
9
9
|
|
|
10
10
|
`PlanPoint`, `PlanView` and `PlanSelection` are the ones that also appear in `RoomDrawer` and `RoomViewer` props. Every exported function's own option and result types come with it — `WallAttrs`, `SplitWallResult`, `WallPathResult` and the rest.
|
|
@@ -80,7 +80,7 @@ const { floor: refreshed, rooms, issues } = derivePlan(floor);
|
|
|
80
80
|
|
|
81
81
|
`derivePlan` extracts the faces and attaches stored metadata. It is pure and **never creates or deletes a `PlanRoom`**, so it is safe to call on every render. Memoise it on `plan.revision`, which every mutation bumps.
|
|
82
82
|
|
|
83
|
-
`commitDerivation(floor)` mints a `PlanRoom` for each face that matched nothing — call it once per committed edit, not per render.
|
|
83
|
+
`commitDerivation(floor, options?)` mints a `PlanRoom` for each face that matched nothing — call it once per committed edit, not per render. It names them `Room 1`, `Room 2`, … counting the floor's rooms and skipping any name already taken; `nameFor: (n, face) => string` replaces the name with the same numbering, so `` (n) => `Raum ${n}` `` gives `Raum 3` on a floor with two rooms. `addFloor` takes the same `nameFor` for `Floor 2`, `Floor 3`, …, and `duplicateFloor` a `label` in place of `<name> copy`.
|
|
84
84
|
|
|
85
85
|
Each `DerivedRoom` carries the face (`outer`, `holes`, `area`, `perimeter`, `wallIds`), the matched `meta`, and an `anchor` guaranteed to be **inside** the polygon (an area centroid can fall outside a concave room, so it is computed, not averaged).
|
|
86
86
|
|
|
@@ -172,6 +172,22 @@ else if (issues.length) console.warn(issues); // loaded, but repaired
|
|
|
172
172
|
|
|
173
173
|
`revision` is bumped on load, since `derivePlan` memoises on it and the repaired plan is not the one the file described.
|
|
174
174
|
|
|
175
|
+
### On a server
|
|
176
|
+
|
|
177
|
+
`@ahrowe/ui/floor-plan` is the whole model, and only the model: every function and type on this page, with no React, react-dom or FontAwesome behind it and no `'use client'` in front of it. That is what lets a Node server check a plan with the same code the client drew it with, instead of storing whatever it was sent.
|
|
178
|
+
|
|
179
|
+
```ts
|
|
180
|
+
import { planFromJson, validatePlan } from '@ahrowe/ui/floor-plan';
|
|
181
|
+
|
|
182
|
+
export function readPlan(json: string) {
|
|
183
|
+
const { plan, issues } = planFromJson(json);
|
|
184
|
+
if (!plan) throw new Error(issues.join('; '));
|
|
185
|
+
return { plan, repaired: issues, broken: plan.floors.flatMap((floor) => validatePlan(floor)) };
|
|
186
|
+
}
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
`@ahrowe/ui` exports the same functions, so client code can keep importing from there.
|
|
190
|
+
|
|
175
191
|
## Snapping and pointer input
|
|
176
192
|
|
|
177
193
|
```tsx
|
|
@@ -195,18 +211,6 @@ const issues = validatePlan(floor); // O(walls²) — development and tests, not
|
|
|
195
211
|
|
|
196
212
|
The invariant that matters: **no two walls may cross without a node at the intersection, and no node may sit on a wall's interior without that wall being split there.** Break either and the face walk silently merges two rooms into one figure-eight face with no error anywhere, which is why `UnsplitCrossing` and `UnsplitNodeOnWall` exist as explicit issue kinds. Everything built through `addWall` maintains this automatically.
|
|
197
213
|
|
|
198
|
-
## Importing older plans
|
|
199
|
-
|
|
200
|
-
```tsx
|
|
201
|
-
import { planFromLegacySvg } from '@ahrowe/ui';
|
|
202
|
-
|
|
203
|
-
// The old canvas was unitless; pick the factor that makes it millimetres.
|
|
204
|
-
// A 400-unit-wide export meant to be a 12m house wants scale: 30.
|
|
205
|
-
const plan = planFromLegacySvg(svgText, { scale: 30 });
|
|
206
|
-
```
|
|
207
|
-
|
|
208
|
-
Feeding every legacy polygon edge through `addWall` is what collapses the old duplicated walls: the second room's copy of a shared edge resolves to the same two nodes and is recognised as already walled. Room names carry across, and doors are recovered where the old swing-arc path is recognisable; anything that is not is skipped rather than guessed at.
|
|
209
|
-
|
|
210
214
|
## Ready for 3D
|
|
211
215
|
|
|
212
216
|
`buildPlanMesh(floor, options?)` turns a storey into triangles: wall solids with their openings cut out, and a slab under each room.
|
package/docs/ProgressBar.md
CHANGED
|
@@ -7,15 +7,15 @@
|
|
|
7
7
|
**Import:** `import { ProgressBar } from '@ahrowe/ui'`
|
|
8
8
|
|
|
9
9
|
```tsx
|
|
10
|
-
import { ProgressBar } from '@ahrowe/ui';
|
|
10
|
+
import { ProgressBar, ThemeColor } from '@ahrowe/ui';
|
|
11
11
|
|
|
12
12
|
// Simple percentage
|
|
13
13
|
<ProgressBar progress={75} total={100} />
|
|
14
14
|
|
|
15
|
-
// Single progress with label
|
|
15
|
+
// Single progress with label, in a theme colour
|
|
16
16
|
<ProgressBar
|
|
17
17
|
total={100}
|
|
18
|
-
progress={{ amount: 60, label: 'Used', color:
|
|
18
|
+
progress={{ amount: 60, label: 'Used', color: ThemeColor.Warn }}
|
|
19
19
|
/>
|
|
20
20
|
|
|
21
21
|
// Stacked / segmented bar
|
|
@@ -39,9 +39,12 @@ import { ProgressBar } from '@ahrowe/ui';
|
|
|
39
39
|
**Progress object:**
|
|
40
40
|
|
|
41
41
|
```ts
|
|
42
|
-
{ amount: number; label?: string; color?:
|
|
42
|
+
{ amount: number; label?: string; color?: ColorValue; class?: string }
|
|
43
43
|
```
|
|
44
44
|
|
|
45
|
+
`color` is a `ThemeColor` or any CSS colour (see [ThemeColor.md](ThemeColor.md)), `--primary-color`
|
|
46
|
+
when unset. A label on a coloured segment is black or white, whichever reads on it.
|
|
47
|
+
|
|
45
48
|
**Theming:** override theme-wide via `ThemeProvider`'s `variables`, or per instance via `style`; falls back to a built-in default when unset:
|
|
46
49
|
|
|
47
50
|
| Variable | Falls back to |
|
package/docs/RoomDrawer.md
CHANGED
|
@@ -246,7 +246,7 @@ ref.current?.deleteSelection();
|
|
|
246
246
|
| `wallThickness` / `wallHeight` | `number` | Millimetres, applied to newly drawn walls |
|
|
247
247
|
| `openingDefaults` | `Partial<Record<OpeningKind, { width?, sill?, head? }>>` | Size of newly placed openings |
|
|
248
248
|
| `showMeasurements` | `boolean` | Live length, angle and area readouts while drawing (default `true`) |
|
|
249
|
-
| `formatLength` / `formatArea` | `(
|
|
249
|
+
| `formatLength` / `formatArea` / `formatAngle` / `formatZoom` | `(value) => string` | Override the readouts: millimetres, mm², degrees from -180 to 180, and zoom in screen px per mm. See [Localisation](#localisation) |
|
|
250
250
|
| `showToolbar` / `showInspector` / `showHint` / `showHistoryControls` / `showFileControls` / `showFloorBar` | `boolean` | Hide parts of the chrome |
|
|
251
251
|
| `floorId` / `defaultFloorId` / `onFloorChange` | `string` / `string` / `(id) => void` | Which storey is being edited |
|
|
252
252
|
| `showUnderlay` | `boolean` | Trace the storey below behind this one (default `true`) |
|
|
@@ -258,7 +258,7 @@ ref.current?.deleteSelection();
|
|
|
258
258
|
| `disabled` | `boolean` | No interaction at all |
|
|
259
259
|
| `canvasHeight` | `string` | Any CSS length (default `'420px'`) |
|
|
260
260
|
| `getRoomColor` / `renderRoomLabel` | | Per-room fill colour and label content |
|
|
261
|
-
| `labels` / `icons` | `RoomDrawerLabels` / `RoomDrawerIcons` | Localise or re-icon the chrome |
|
|
261
|
+
| `labels` / `icons` | `RoomDrawerLabels` / `RoomDrawerIcons` | Localise or re-icon the chrome, and name new rooms and floors |
|
|
262
262
|
|
|
263
263
|
`RoomDrawerProps` extends the full native `div` attribute set plus `data-*`, so `id`, `title`, `aria-*` and the rest pass through to the root.
|
|
264
264
|
|
|
@@ -292,7 +292,7 @@ Floors are part of the plan document, so they survive a download and reopen with
|
|
|
292
292
|
|
|
293
293
|
A bar under the canvas shows what is selected and what can be done with it: a name for a room, thickness for a wall, width and sill for an opening, and delete for any of them. It is **always there and always the same height**, including when nothing is selected — it used to appear on selection and size itself to its contents, which moved the canvas out from under the pointer by up to 116px as you clicked between a corner and a wall.
|
|
294
294
|
|
|
295
|
-
Each selection is named on the left (`Room`, `Wall`, `Door`, `Corner`, `3 selected`), which is the whole content of the bar for a corner: a corner has nothing to edit that dragging it does not already do. Delete sits at the far end, apart from the fields, since it is the one action that applies to every kind of selection and the only destructive one. Override any of the names through `labels` (`selectedRoom`, `selectedWall`, `selectedCorner`, `
|
|
295
|
+
Each selection is named on the left (`Room`, `Wall`, `Door`, `Corner`, `3 selected`), which is the whole content of the bar for a corner: a corner has nothing to edit that dragging it does not already do. Delete sits at the far end, apart from the fields, since it is the one action that applies to every kind of selection and the only destructive one. Override any of the names through `labels` (`selectedRoom`, `selectedWall`, `selectedCorner`, `selectedDoor`, `selectedWindow`, `selectedArchway`, `selectedGap`, `selectedCount`), and hide the bar with `showInspector={false}`.
|
|
296
296
|
|
|
297
297
|
**Sill**, on an opening, is how far above the floor it starts: 0 for a door, around 900 for a window. It changes nothing in the plan, because a plan is a horizontal cut and every opening looks the same from above. It is stored so the same plan can drive a 3D view later without anyone having to supply the heights again — as are `head` (the top of the opening), `PlanWall.height` and `PlanFloor.elevation`.
|
|
298
298
|
|
|
@@ -358,20 +358,49 @@ Stated plainly: **a free-form drawing canvas cannot be fully operated from a key
|
|
|
358
358
|
|
|
359
359
|
The root is `role="application"` (justified here, since single-letter keys are intercepted), the toolbar is a real `role="toolbar"` of `<button>`s with `aria-pressed`, and room labels render with a halo so they stay legible over any fill colour a consumer sets.
|
|
360
360
|
|
|
361
|
-
##
|
|
361
|
+
## Localisation
|
|
362
362
|
|
|
363
|
-
|
|
363
|
+
Every string the drawer produces goes through `labels`, and every number it prints through a `format*` prop. Set them once, app-wide: labels merge per key, so an instance that overrides one string keeps the rest.
|
|
364
|
+
|
|
365
|
+
Some of those strings end up **in the plan**, not only on screen: the names of the rooms and floors the drawer creates. A plan saved before they were translated keeps "Room 1" and "Ground floor" for good, so set them from the start.
|
|
364
366
|
|
|
365
|
-
|
|
367
|
+
```tsx
|
|
368
|
+
const number = new Intl.NumberFormat('de-AT', { maximumFractionDigits: 1 });
|
|
369
|
+
const percent = new Intl.NumberFormat('de-AT', { style: 'percent', maximumFractionDigits: 1 });
|
|
370
|
+
|
|
371
|
+
<AhroweProvider
|
|
372
|
+
defaultProps={{
|
|
373
|
+
RoomDrawer: {
|
|
374
|
+
labels: {
|
|
375
|
+
newRoomName: (n) => `Raum ${n}`,
|
|
376
|
+
newFloorName: (n) => `Etage ${n}`,
|
|
377
|
+
copiedFloorName: (name) => `${name} (Kopie)`,
|
|
378
|
+
initialFloorName: 'Erdgeschoss',
|
|
379
|
+
angleLock: (angle) => `Auf ${angle}°-Schritte einrasten`,
|
|
380
|
+
selectedCount: (count) => `${count} ausgewählt`,
|
|
381
|
+
selectedDoor: 'Tür',
|
|
382
|
+
hintSelect: 'Ecke ziehen zum Umformen · …',
|
|
383
|
+
hintSelectSingle: 'Ecke ziehen zum Umformen · …',
|
|
384
|
+
},
|
|
385
|
+
formatLength: (mm) => `${number.format(mm / 1000)} m`,
|
|
386
|
+
formatArea: (mm2) => `${number.format(mm2 / 1e6)} m²`,
|
|
387
|
+
formatAngle: (degrees) => `${number.format(degrees)}°`,
|
|
388
|
+
formatZoom: (zoom) => percent.format(zoom),
|
|
389
|
+
},
|
|
390
|
+
}}
|
|
391
|
+
>
|
|
392
|
+
<App />
|
|
393
|
+
</AhroweProvider>
|
|
394
|
+
```
|
|
366
395
|
|
|
367
|
-
|
|
396
|
+
A label that carries a value is a function of it: `angleLock` gets `constrainAngle`, `selectedCount` the count, `copiedFloorName` the name of the floor being copied, and `newRoomName` and `newFloorName` the next number whose name is not taken yet. `hintSelect` is the hint with `multiSelect` on and `hintSelectSingle` the one with it off. `formatZoom` gets screen pixels per millimetre, which is the fraction `Intl`'s `percent` style expects.
|
|
368
397
|
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
398
|
+
Two texts are not in `labels`. The root's accessible name is the `aria-label` prop (default "Floor plan editor"), which `defaultProps` can set as well. The repair report after opening a file is `planFromJson`'s list of English sentences, shown as it comes; `onImport` receives it too, if you would rather show your own.
|
|
399
|
+
|
|
400
|
+
## Global defaults
|
|
401
|
+
|
|
402
|
+
Adopts `ConfigProvider`, e.g. `defaultProps={{ RoomDrawer: { gridSize: 250, showGrid: false } }}`. See [ConfigProvider.md](ConfigProvider.md).
|
|
374
403
|
|
|
375
404
|
**Slots:** `root` `toolbar` `toolButton` `toolIcon` `viewControls` `viewButton` `zoomLabel` `canvasWrapper` `canvas` `grid` `rooms` `roomFill` `roomLabel` `walls` `wallBody` `openings` `opening` `overlay` `measureLine` `floorBar` `floorTab` `inspector` `inspectorLabel` `inspectorField` `hint`
|
|
376
405
|
|
|
377
|
-
**Labels:** every string the drawer's own chrome renders, including `tools`, `storeyHeightHint` and `sillHeightHint
|
|
406
|
+
**Labels:** every string the drawer's own chrome renders, including `tools`, `storeyHeightHint` and `sillHeightHint`, and the names it gives new rooms and floors. Type: `RoomDrawerLabels`.
|
package/docs/RoomViewer.md
CHANGED
|
@@ -72,7 +72,7 @@ Walls are drawn as mass rather than as ink: the body is `var(--text-color)` mixe
|
|
|
72
72
|
| `getRoomColor` / `renderRoomLabel` / `getRoomLabel` / `formatArea` | functions | Colour, label and area rendering |
|
|
73
73
|
| `height` | `number \| string` | Canvas height (default `360`) |
|
|
74
74
|
| `emptyState` | `ReactNode` | Shown when there is no plan, or nothing in it |
|
|
75
|
-
| `labels` / `icons` | objects | Every string and icon in the chrome |
|
|
75
|
+
| `labels` / `icons` | objects | Every string and icon in the chrome. `selectedRoom` is `(name, area) => string`, and `unnamedRoom` stands in for a room with no name |
|
|
76
76
|
|
|
77
77
|
**Imperative handle:** `fitToContent(options?)`, `getView()`, `setView(view)`, `zoomBy(factor)`, `select(roomId)`, `getFloorId()`, `setFloorId(id)`, `getSvgElement()`.
|
|
78
78
|
|
|
@@ -81,16 +81,3 @@ Walls are drawn as mass rather than as ink: the body is `var(--text-color)` mixe
|
|
|
81
81
|
## Accessibility, honestly
|
|
82
82
|
|
|
83
83
|
A free-form plan cannot be fully keyboard operated, and this does not pretend otherwise. What it does give you: every room is a focusable `role="button"` with an accessible name, `Enter`/`Space` select, the floor tabs are real buttons, the zoom controls are real buttons, and the current selection is announced. Panning and zooming are pointer-only; the zoom buttons and `fitToContent()` are the keyboard path.
|
|
84
|
-
|
|
85
|
-
## Migration from the previous version
|
|
86
|
-
|
|
87
|
-
The old viewer took `data: { label, data: ReactNode }[]` — an array of **pre-rendered SVG elements** — and found rooms by looking for `id="room…"`, highlighting them by mutating `classList`. That is gone, and there is no shim: the old `data` was a React element rather than a string, so there is nothing to parse at runtime.
|
|
88
|
-
|
|
89
|
-
| Before | Now |
|
|
90
|
-
|--------|-----|
|
|
91
|
-
| `data={[{ label, data: <svg/> }]}` | `plan={plan}` — one `FloorPlan`, floors and all |
|
|
92
|
-
| `id="room12"` convention | `PlanRoom` ids in the model |
|
|
93
|
-
| Highlighting via `classList` | `selectedRoomId` / `hoveredRoomId` |
|
|
94
|
-
| No selection callback | `onSelect(roomId, room, floorId)` |
|
|
95
|
-
|
|
96
|
-
To bring an old SVG across, run it through `planFromLegacySvg` once and keep the resulting plan. See [FloorPlan](./FloorPlan.md).
|
package/docs/SectionHeader.md
CHANGED
|
@@ -77,7 +77,7 @@ import { faFolder, faPen, faTrash } from '@fortawesome/free-solid-svg-icons';
|
|
|
77
77
|
interface SectionHeaderAction {
|
|
78
78
|
title?: string;
|
|
79
79
|
icon: IconDefinition | ReactElement;
|
|
80
|
-
onClick?: (e: React.MouseEvent<
|
|
80
|
+
onClick?: (e: React.MouseEvent<HTMLButtonElement>) => void;
|
|
81
81
|
}
|
|
82
82
|
```
|
|
83
83
|
|