@flux-ui/components 3.0.0-next.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.
Files changed (261) hide show
  1. package/README.md +45 -0
  2. package/package.json +77 -0
  3. package/src/component/FluxAction.vue +27 -0
  4. package/src/component/FluxActionBar.vue +94 -0
  5. package/src/component/FluxActionPane.vue +40 -0
  6. package/src/component/FluxActions.vue +27 -0
  7. package/src/component/FluxAlert.vue +37 -0
  8. package/src/component/FluxAnimatedColors.vue +141 -0
  9. package/src/component/FluxAspectRatio.vue +21 -0
  10. package/src/component/FluxAutoGrid.vue +27 -0
  11. package/src/component/FluxAvatar.vue +119 -0
  12. package/src/component/FluxBadge.vue +84 -0
  13. package/src/component/FluxBadgeStack.vue +18 -0
  14. package/src/component/FluxBorderShine.vue +36 -0
  15. package/src/component/FluxBoxedIcon.vue +36 -0
  16. package/src/component/FluxButton.vue +110 -0
  17. package/src/component/FluxButtonGroup.vue +15 -0
  18. package/src/component/FluxButtonStack.vue +28 -0
  19. package/src/component/FluxCalendar.vue +254 -0
  20. package/src/component/FluxCalendarEvent.vue +41 -0
  21. package/src/component/FluxCheckbox.vue +60 -0
  22. package/src/component/FluxChip.vue +57 -0
  23. package/src/component/FluxClickablePane.vue +61 -0
  24. package/src/component/FluxColorPicker.vue +265 -0
  25. package/src/component/FluxColorSelect.vue +81 -0
  26. package/src/component/FluxComment.vue +71 -0
  27. package/src/component/FluxConfirm.vue +42 -0
  28. package/src/component/FluxContainer.vue +23 -0
  29. package/src/component/FluxDataTable.vue +96 -0
  30. package/src/component/FluxDatePicker.vue +353 -0
  31. package/src/component/FluxDestructiveButton.vue +28 -0
  32. package/src/component/FluxDisabled.vue +22 -0
  33. package/src/component/FluxDivider.vue +37 -0
  34. package/src/component/FluxDotPattern.vue +72 -0
  35. package/src/component/FluxDropZone.vue +202 -0
  36. package/src/component/FluxDynamicView.vue +16 -0
  37. package/src/component/FluxExpandable.vue +119 -0
  38. package/src/component/FluxExpandableGroup.vue +53 -0
  39. package/src/component/FluxFader.vue +64 -0
  40. package/src/component/FluxFaderItem.vue +15 -0
  41. package/src/component/FluxFilter.vue +133 -0
  42. package/src/component/FluxFilterDate.vue +58 -0
  43. package/src/component/FluxFilterDateRange.vue +59 -0
  44. package/src/component/FluxFilterOption.vue +49 -0
  45. package/src/component/FluxFilterOptionAsync.vue +103 -0
  46. package/src/component/FluxFilterOptions.vue +62 -0
  47. package/src/component/FluxFilterOptionsAsync.vue +113 -0
  48. package/src/component/FluxFilterRange.vue +91 -0
  49. package/src/component/FluxFlickeringGrid.vue +141 -0
  50. package/src/component/FluxFlyout.vue +205 -0
  51. package/src/component/FluxFocalPointEditor.vue +137 -0
  52. package/src/component/FluxFocalPointImage.vue +29 -0
  53. package/src/component/FluxForm.vue +35 -0
  54. package/src/component/FluxFormColumn.vue +15 -0
  55. package/src/component/FluxFormDateInput.vue +92 -0
  56. package/src/component/FluxFormDateRangeInput.vue +87 -0
  57. package/src/component/FluxFormDateTimeInput.vue +120 -0
  58. package/src/component/FluxFormField.vue +98 -0
  59. package/src/component/FluxFormFieldAddition.vue +37 -0
  60. package/src/component/FluxFormInput.vue +223 -0
  61. package/src/component/FluxFormInputAddition.vue +31 -0
  62. package/src/component/FluxFormInputGroup.vue +25 -0
  63. package/src/component/FluxFormPinInput.vue +135 -0
  64. package/src/component/FluxFormRangeSlider.vue +179 -0
  65. package/src/component/FluxFormRow.vue +15 -0
  66. package/src/component/FluxFormSection.vue +23 -0
  67. package/src/component/FluxFormSelect.vue +59 -0
  68. package/src/component/FluxFormSelectAsync.vue +118 -0
  69. package/src/component/FluxFormSlider.vue +123 -0
  70. package/src/component/FluxFormTextArea.vue +53 -0
  71. package/src/component/FluxFormTimeZonePicker.vue +713 -0
  72. package/src/component/FluxGallery.vue +99 -0
  73. package/src/component/FluxGalleryItem.vue +49 -0
  74. package/src/component/FluxGrid.vue +28 -0
  75. package/src/component/FluxGridColumn.vue +31 -0
  76. package/src/component/FluxGridPattern.vue +60 -0
  77. package/src/component/FluxIcon.vue +79 -0
  78. package/src/component/FluxInfo.vue +28 -0
  79. package/src/component/FluxInfoStack.vue +17 -0
  80. package/src/component/FluxLegend.vue +27 -0
  81. package/src/component/FluxLink.vue +35 -0
  82. package/src/component/FluxMenu.vue +31 -0
  83. package/src/component/FluxMenuGroup.vue +21 -0
  84. package/src/component/FluxMenuItem.vue +84 -0
  85. package/src/component/FluxMenuOptions.vue +38 -0
  86. package/src/component/FluxMenuSubHeader.vue +33 -0
  87. package/src/component/FluxMenuTitle.vue +17 -0
  88. package/src/component/FluxNotice.vue +79 -0
  89. package/src/component/FluxNoticeStack.vue +17 -0
  90. package/src/component/FluxOverlay.vue +31 -0
  91. package/src/component/FluxPagination.vue +148 -0
  92. package/src/component/FluxPaginationBar.vue +81 -0
  93. package/src/component/FluxPane.vue +45 -0
  94. package/src/component/FluxPaneBody.vue +15 -0
  95. package/src/component/FluxPaneDeck.vue +24 -0
  96. package/src/component/FluxPaneFooter.vue +15 -0
  97. package/src/component/FluxPaneGroup.vue +15 -0
  98. package/src/component/FluxPaneHeader.vue +44 -0
  99. package/src/component/FluxPaneIllustration.vue +68 -0
  100. package/src/component/FluxPaneMedia.vue +31 -0
  101. package/src/component/FluxPercentageBar.vue +45 -0
  102. package/src/component/FluxPersona.vue +48 -0
  103. package/src/component/FluxPlaceholder.vue +56 -0
  104. package/src/component/FluxPressable.vue +77 -0
  105. package/src/component/FluxPrimaryButton.vue +28 -0
  106. package/src/component/FluxProgressBar.vue +75 -0
  107. package/src/component/FluxPrompt.vue +77 -0
  108. package/src/component/FluxPublishButton.vue +59 -0
  109. package/src/component/FluxQuantitySelector.vue +109 -0
  110. package/src/component/FluxRemove.vue +34 -0
  111. package/src/component/FluxRoot.vue +60 -0
  112. package/src/component/FluxSecondaryButton.vue +28 -0
  113. package/src/component/FluxSegmentedControl.vue +77 -0
  114. package/src/component/FluxSegmentedView.vue +15 -0
  115. package/src/component/FluxSeparator.vue +19 -0
  116. package/src/component/FluxSlideOver.vue +25 -0
  117. package/src/component/FluxSnackbar.vue +154 -0
  118. package/src/component/FluxSnackbarProvider.vue +34 -0
  119. package/src/component/FluxSpacer.vue +9 -0
  120. package/src/component/FluxSpacing.vue +32 -0
  121. package/src/component/FluxSpinner.vue +48 -0
  122. package/src/component/FluxSplitButton.vue +61 -0
  123. package/src/component/FluxStack.vue +40 -0
  124. package/src/component/FluxStatistic.vue +68 -0
  125. package/src/component/FluxStepper.vue +69 -0
  126. package/src/component/FluxStepperStep.vue +15 -0
  127. package/src/component/FluxStepperSteps.vue +62 -0
  128. package/src/component/FluxTab.vue +23 -0
  129. package/src/component/FluxTabBar.vue +87 -0
  130. package/src/component/FluxTabBarItem.vue +104 -0
  131. package/src/component/FluxTable.vue +68 -0
  132. package/src/component/FluxTableActions.vue +16 -0
  133. package/src/component/FluxTableCell.vue +47 -0
  134. package/src/component/FluxTableHeader.vue +111 -0
  135. package/src/component/FluxTableRow.vue +15 -0
  136. package/src/component/FluxTabs.vue +91 -0
  137. package/src/component/FluxTag.vue +85 -0
  138. package/src/component/FluxTagStack.vue +18 -0
  139. package/src/component/FluxTicks.vue +44 -0
  140. package/src/component/FluxTimeline.vue +17 -0
  141. package/src/component/FluxTimelineItem.vue +73 -0
  142. package/src/component/FluxToggle.vue +64 -0
  143. package/src/component/FluxToolbar.vue +32 -0
  144. package/src/component/FluxToolbarGroup.vue +18 -0
  145. package/src/component/FluxTooltip.vue +56 -0
  146. package/src/component/FluxTooltipProvider.vue +176 -0
  147. package/src/component/FluxWindow.vue +47 -0
  148. package/src/component/index.ts +142 -0
  149. package/src/component/primitive/Anchor.vue +17 -0
  150. package/src/component/primitive/AnchorPopup.vue +194 -0
  151. package/src/component/primitive/CoordinatePicker.vue +155 -0
  152. package/src/component/primitive/CoordinatePickerThumb.vue +71 -0
  153. package/src/component/primitive/FilterItem.vue +44 -0
  154. package/src/component/primitive/FilterMenuRenderer.ts +233 -0
  155. package/src/component/primitive/FilterOptionBase.vue +67 -0
  156. package/src/component/primitive/SelectBase.vue +340 -0
  157. package/src/component/primitive/SliderBase.vue +89 -0
  158. package/src/component/primitive/SliderThumb.vue +64 -0
  159. package/src/component/primitive/SliderTrack.vue +22 -0
  160. package/src/component/primitive/VNodeRenderer.ts +11 -0
  161. package/src/component/primitive/index.ts +10 -0
  162. package/src/composable/index.ts +9 -0
  163. package/src/composable/private/index.ts +3 -0
  164. package/src/composable/private/useFormSelect.ts +66 -0
  165. package/src/composable/private/useLoaded.ts +21 -0
  166. package/src/composable/private/useTranslate.ts +35 -0
  167. package/src/composable/useBreakpoints.ts +54 -0
  168. package/src/composable/useDisabled.ts +9 -0
  169. package/src/composable/useDisabledInjection.ts +6 -0
  170. package/src/composable/useExpandableGroupInjection.ts +10 -0
  171. package/src/composable/useFilterInjection.ts +22 -0
  172. package/src/composable/useFlyoutInjection.ts +10 -0
  173. package/src/composable/useFormFieldInjection.ts +8 -0
  174. package/src/composable/useTableInjection.ts +11 -0
  175. package/src/css/base.scss +33 -0
  176. package/src/css/component/Action.module.scss +107 -0
  177. package/src/css/component/Avatar.module.scss +177 -0
  178. package/src/css/component/Badge.module.scss +189 -0
  179. package/src/css/component/Button.module.scss +293 -0
  180. package/src/css/component/Calendar.module.scss +171 -0
  181. package/src/css/component/Chip.module.scss +58 -0
  182. package/src/css/component/Color.module.scss +184 -0
  183. package/src/css/component/Comment.module.scss +123 -0
  184. package/src/css/component/DatePicker.module.scss +193 -0
  185. package/src/css/component/Divider.module.scss +79 -0
  186. package/src/css/component/DropZone.module.scss +99 -0
  187. package/src/css/component/Expandable.module.scss +112 -0
  188. package/src/css/component/Fader.module.scss +38 -0
  189. package/src/css/component/Filter.module.scss +80 -0
  190. package/src/css/component/Flyout.module.scss +63 -0
  191. package/src/css/component/FocalPoint.module.scss +84 -0
  192. package/src/css/component/Form.module.scss +812 -0
  193. package/src/css/component/Gallery.module.scss +64 -0
  194. package/src/css/component/Grid.module.scss +24 -0
  195. package/src/css/component/Icon.module.scss +104 -0
  196. package/src/css/component/Info.module.scss +15 -0
  197. package/src/css/component/Layout.module.scss +63 -0
  198. package/src/css/component/Legend.module.scss +32 -0
  199. package/src/css/component/Menu.module.scss +314 -0
  200. package/src/css/component/Notice.module.scss +279 -0
  201. package/src/css/component/Overlay.module.scss +149 -0
  202. package/src/css/component/Pagination.module.scss +59 -0
  203. package/src/css/component/Pane.module.scss +218 -0
  204. package/src/css/component/PercentageBar.module.scss +31 -0
  205. package/src/css/component/Placeholder.module.scss +72 -0
  206. package/src/css/component/Progress.module.scss +84 -0
  207. package/src/css/component/Remove.module.scss +29 -0
  208. package/src/css/component/Root.module.scss +8 -0
  209. package/src/css/component/SegmentedControl.module.scss +82 -0
  210. package/src/css/component/Snackbar.module.scss +227 -0
  211. package/src/css/component/Spinner.module.scss +36 -0
  212. package/src/css/component/Statistic.module.scss +118 -0
  213. package/src/css/component/Stepper.module.scss +103 -0
  214. package/src/css/component/Tab.module.scss +162 -0
  215. package/src/css/component/Table.module.scss +164 -0
  216. package/src/css/component/Timeline.module.scss +173 -0
  217. package/src/css/component/Toolbar.module.scss +82 -0
  218. package/src/css/component/Tooltip.module.scss +62 -0
  219. package/src/css/component/Transition.module.scss +142 -0
  220. package/src/css/component/Visual.module.scss +70 -0
  221. package/src/css/component/base/Button.module.scss +87 -0
  222. package/src/css/component/base/Effect.module.scss +139 -0
  223. package/src/css/component/base/Grid.module.scss +8 -0
  224. package/src/css/component/base/Pane.module.scss +54 -0
  225. package/src/css/component/primitive/CoordinatePicker.module.scss +24 -0
  226. package/src/css/component/primitive/Slider.module.scss +116 -0
  227. package/src/css/index.scss +5 -0
  228. package/src/css/layers.scss +1 -0
  229. package/src/css/mixin/breakpoints.scss +112 -0
  230. package/src/css/mixin/focus-ring.scss +56 -0
  231. package/src/css/mixin/hover.scss +7 -0
  232. package/src/css/mixin/index.scss +3 -0
  233. package/src/css/reset.scss +169 -0
  234. package/src/css/typography.scss +87 -0
  235. package/src/css/variables.scss +214 -0
  236. package/src/data/di.ts +42 -0
  237. package/src/data/filter.ts +9 -0
  238. package/src/data/helper.ts +9 -0
  239. package/src/data/i18n.ts +55 -0
  240. package/src/data/iconRegistry.ts +21 -0
  241. package/src/data/index.ts +8 -0
  242. package/src/data/inputMask.ts +34 -0
  243. package/src/data/store.ts +233 -0
  244. package/src/image/avatar-mask.svg +3 -0
  245. package/src/index.ts +25 -0
  246. package/src/transition/FluxAutoHeightTransition.vue +59 -0
  247. package/src/transition/FluxAutoWidthTransition.vue +59 -0
  248. package/src/transition/FluxBreakthroughTransition.vue +23 -0
  249. package/src/transition/FluxFadeTransition.vue +24 -0
  250. package/src/transition/FluxOverlayTransition.vue +22 -0
  251. package/src/transition/FluxRouteTransition.vue +23 -0
  252. package/src/transition/FluxSlideOverTransition.vue +22 -0
  253. package/src/transition/FluxTooltipTransition.vue +22 -0
  254. package/src/transition/FluxVerticalWindowTransition.vue +23 -0
  255. package/src/transition/FluxWindowTransition.vue +23 -0
  256. package/src/transition/index.ts +10 -0
  257. package/src/util/createDialogRenderer.ts +64 -0
  258. package/src/util/createLabelForDateRange.ts +61 -0
  259. package/src/util/index.ts +2 -0
  260. package/src/vite.d.ts +13 -0
  261. package/tsconfig.json +45 -0
package/README.md ADDED
@@ -0,0 +1,45 @@
1
+ # Flux
2
+
3
+ This repository contains the source code for the basic components that are used throughout our front-end projects. It
4
+ targets Vue 3+. Please read the following instructions and checks in order to proceed.
5
+
6
+ ## 📦 Registry
7
+
8
+ - The UI library package is available under `@flux-ui/components`.
9
+ - The Dashboard library package is available under `@flux-ui/dashboard`.
10
+ - The internal package is available under `@flux-ui/internals`.
11
+
12
+ ## ⚠️ Requirements
13
+
14
+ - Install Node.js ^22
15
+ - Install pnpm using `npm i -g pnpm`.
16
+ - Configure a new environment variable `FONTAWESOME_NPM_AUTH_TOKEN`. This should be a valid Font Awesome private npm auth token.
17
+ - Use `pnpm install` to install the required packages.
18
+ - Use `pnpm dev` to start a build watcher for both targets.
19
+ - Use `pnpm build` to build a production bundle.
20
+ - Use `pnpm link` to link the dist folder of flux to your global node_modules.
21
+
22
+ ## 🪵 Git
23
+
24
+ All commit messages and branches will be in English.
25
+
26
+ ### Branches
27
+
28
+ - **Main** — Contains the latest stable release and is the exact source that is running in production.
29
+ - **Develop** — Contains the latest staging release that is marked for deployment and is the exact source that is running on staging.
30
+ - **Feature branches** — Any feature should have its own feature branch. Once complete, the branch should be merged into the _develop_ branch and the feature branch should be deleted.
31
+ - **Bugfix branches** — When a bug is found, it should be fixed within a bugfix branch. Once complete the branch should be merged into the _develop_ branch and the feature branch should be deleted.
32
+
33
+ ### Commit messages
34
+
35
+ Commit messages are bound to the following templates:
36
+
37
+ - `<type>: <message> `
38
+ - `<type>(<feature>): <message>`
39
+ - `<type>(<feature>): <message> [<issue-number>]`
40
+
41
+ #### Examples
42
+
43
+ - `feat(expandable): adds header slot to expandable.`
44
+ - `feat(expandable): adds header slot to expandable. [FLUX-123]`
45
+ - `chore: adds vue 3 build target.`
package/package.json ADDED
@@ -0,0 +1,77 @@
1
+ {
2
+ "name": "@flux-ui/components",
3
+ "description": "A set of opiniated UI components.",
4
+ "version": "3.0.0-next.0",
5
+ "type": "module",
6
+ "license": "MIT",
7
+ "funding": "https://github.com/sponsors/basmilius",
8
+ "homepage": "https://flux.bas.dev",
9
+ "repository": {
10
+ "type": "git",
11
+ "url": "git+https://github.com/basmilius/flux.git",
12
+ "directory": "packages/components"
13
+ },
14
+ "keywords": [
15
+ "ui library",
16
+ "component library",
17
+ "design system",
18
+ "vue",
19
+ "vue 3",
20
+ "ui",
21
+ "components",
22
+ "flux"
23
+ ],
24
+ "scripts": {
25
+ "build": "vue-tsc && vite build",
26
+ "dev": "vite build --mode dev --watch",
27
+ "prepublishOnly": "cp ../../README.md ."
28
+ },
29
+ "engines": {
30
+ "node": ">=23"
31
+ },
32
+ "exports": {
33
+ ".": {
34
+ "types": "./dist/index.d.ts",
35
+ "default": "./dist/flux.js"
36
+ },
37
+ "./style.css": "./dist/flux.css",
38
+ "./*": "./*"
39
+ },
40
+ "publishConfig": {
41
+ "access": "public",
42
+ "provenance": true
43
+ },
44
+ "files": [
45
+ "dist",
46
+ "src",
47
+ "tsconfig.json"
48
+ ],
49
+ "main": "./dist/flux.js",
50
+ "module": "./dist/flux.js",
51
+ "types": "./dist/index.d.ts",
52
+ "typings": "./dist/index.d.ts",
53
+ "sideEffects": false,
54
+ "dependencies": {
55
+ "@basmilius/utils": "^1.12.0",
56
+ "@flux-ui/internals": "3.0.0-next.0",
57
+ "@flux-ui/types": "3.0.0-next.0",
58
+ "@fortawesome/fontawesome-common-types": "^6.7.2",
59
+ "clsx": "^2.1.1",
60
+ "imask": "^7.6.1",
61
+ "lodash-es": "^4.17.21",
62
+ "luxon": "^3.6.1",
63
+ "vue": "^3.5.13"
64
+ },
65
+ "devDependencies": {
66
+ "@basmilius/vite-vue-preset": "^2.5.0",
67
+ "@types/lodash-es": "^4.17.12",
68
+ "@types/luxon": "^3.6.2",
69
+ "@types/node": "^22.14.0",
70
+ "@vitejs/plugin-vue": "^5.2.3",
71
+ "pinia": "^3.0.1",
72
+ "sass-embedded": "^1.86.3",
73
+ "typescript": "^5.8.3",
74
+ "vite": "^6.2.5",
75
+ "vue-tsc": "^2.2.8"
76
+ }
77
+ }
@@ -0,0 +1,27 @@
1
+ <template>
2
+ <FluxButton
3
+ :="{disabled, isLoading, label, href, rel, target, to, type}"
4
+ :css-class="$style.action"
5
+ :css-class-icon="$style.actionIcon"
6
+ :css-class-label="$style.actionLabel"
7
+ :class="isDestructive && $style.isDestructive"
8
+ :icon-leading="icon"
9
+ @click="$emit('click', $event)"
10
+ @mouseenter="$emit('mouseenter', $event)"
11
+ @mouseleave="$emit('mouseleave', $event)"/>
12
+ </template>
13
+
14
+ <script
15
+ lang="ts"
16
+ setup>
17
+ import type { FluxButtonEmits, FluxButtonProps, FluxIconName } from '@flux-ui/types';
18
+ import FluxButton from './FluxButton.vue';
19
+ import $style from '$flux/css/component/Action.module.scss';
20
+
21
+ defineEmits<FluxButtonEmits>();
22
+
23
+ defineProps<Omit<FluxButtonProps, 'iconLeading' | 'iconTrailing' | 'isFilled' | 'size'> & {
24
+ readonly icon?: FluxIconName;
25
+ readonly isDestructive?: boolean;
26
+ }>();
27
+ </script>
@@ -0,0 +1,94 @@
1
+ <template>
2
+ <FluxStack
3
+ :class="$style.actionBar"
4
+ direction="horizontal"
5
+ :gap="9">
6
+ <slot name="primary"/>
7
+ <slot name="actionsStart"/>
8
+
9
+ <FluxSpacer/>
10
+
11
+ <slot name="actionsBeforeSearch"/>
12
+ <slot name="search"/>
13
+ <slot name="actionsAfterSearch"/>
14
+
15
+ <FluxFlyout v-if="slots.filter">
16
+ <template #opener="{close, open, toggle}">
17
+ <slot
18
+ v-bind="{close, open, toggle}"
19
+ name="filterOpener">
20
+ <FluxButtonGroup>
21
+ <FluxSecondaryButton
22
+ icon-leading="filter"
23
+ :label="translate('flux.filter')"
24
+ @click="open"/>
25
+
26
+ <FluxTooltip
27
+ v-if="isResettable"
28
+ :content="translate('flux.filterReset')">
29
+ <FluxDestructiveButton
30
+ icon-leading="xmark"
31
+ @click="$emit('reset')"/>
32
+ </FluxTooltip>
33
+ </FluxButtonGroup>
34
+ </slot>
35
+ </template>
36
+
37
+ <template #default="{close, paneX, paneY, openerWidth, openerHeight}">
38
+ <slot
39
+ name="filter"
40
+ v-bind="{close, paneX, paneY, openerWidth, openerHeight}"/>
41
+ </template>
42
+ </FluxFlyout>
43
+
44
+ <slot name="actionsEnd"/>
45
+ </FluxStack>
46
+ </template>
47
+
48
+ <script
49
+ lang="ts"
50
+ setup>
51
+ import { useTranslate } from '$flux/composable/private';
52
+ import FluxButtonGroup from './FluxButtonGroup.vue';
53
+ import FluxDestructiveButton from './FluxDestructiveButton.vue';
54
+ import FluxFlyout from './FluxFlyout.vue';
55
+ import FluxSecondaryButton from './FluxSecondaryButton.vue';
56
+ import FluxSpacer from './FluxSpacer.vue';
57
+ import FluxStack from './FluxStack.vue';
58
+ import FluxTooltip from './FluxTooltip.vue';
59
+ import $style from '$flux/css/component/Action.module.scss';
60
+
61
+ defineEmits<{
62
+ reset: [];
63
+ }>();
64
+
65
+ defineProps<{
66
+ readonly isResettable?: boolean;
67
+ }>();
68
+
69
+ const slots = defineSlots<{
70
+ primary?(): any;
71
+ actionsEnd?(): any;
72
+ actionsStart?(): any;
73
+ actionsAfterSearch?(): any;
74
+ actionsBeforeSearch?(): any;
75
+ search?(): any;
76
+
77
+ filter?(props: {
78
+ close(): void;
79
+
80
+ readonly paneX: number;
81
+ readonly paneY: number;
82
+ readonly openerWidth: number;
83
+ readonly openerHeight: number;
84
+ }): any;
85
+
86
+ filterOpener?(props: {
87
+ close(): void;
88
+ open(): void;
89
+ toggle(): void;
90
+ }): any;
91
+ }>();
92
+
93
+ const translate = useTranslate();
94
+ </script>
@@ -0,0 +1,40 @@
1
+ <template>
2
+ <FluxPane
3
+ :class="$style.actionPane"
4
+ :variant="paneVariant">
5
+ <slot name="base"/>
6
+
7
+ <div :class="$style.actionPaneGrid">
8
+ <FluxPaneBody :class="$style.actionPaneBody">
9
+ <slot/>
10
+ </FluxPaneBody>
11
+
12
+ <FluxPaneBody
13
+ v-if="slots.buttons"
14
+ :class="$style.actionPaneBody">
15
+ <FluxButtonStack direction="vertical">
16
+ <slot name="buttons"/>
17
+ </FluxButtonStack>
18
+ </FluxPaneBody>
19
+ </div>
20
+ </FluxPane>
21
+ </template>
22
+
23
+ <script
24
+ lang="ts"
25
+ setup>
26
+ import FluxButtonStack from './FluxButtonStack.vue';
27
+ import FluxPane from './FluxPane.vue';
28
+ import FluxPaneBody from './FluxPaneBody.vue';
29
+ import $style from '$flux/css/component/Action.module.scss';
30
+
31
+ defineProps<{
32
+ readonly paneVariant?: 'default' | 'flat' | 'well';
33
+ }>();
34
+
35
+ const slots = defineSlots<{
36
+ default?(): any;
37
+ buttons?(): any;
38
+ base?(): any;
39
+ }>();
40
+ </script>
@@ -0,0 +1,27 @@
1
+ <template>
2
+ <FluxStack
3
+ ref="element"
4
+ direction="horizontal"
5
+ :gap="1"
6
+ tag="nav">
7
+ <slot/>
8
+ </FluxStack>
9
+ </template>
10
+
11
+ <script
12
+ lang="ts"
13
+ setup>
14
+ import { useFocusZone } from '@flux-ui/internals';
15
+ import { useTemplateRef } from 'vue';
16
+ import FluxStack from './FluxStack.vue';
17
+
18
+ defineSlots<{
19
+ default(): any;
20
+ }>();
21
+
22
+ const elementRef = useTemplateRef('element');
23
+
24
+ useFocusZone(elementRef, {
25
+ direction: 'horizontal'
26
+ });
27
+ </script>
@@ -0,0 +1,37 @@
1
+ <template>
2
+ <FluxPane>
3
+ <FluxPaneHeader
4
+ :icon="alert.icon"
5
+ :title="alert.title"/>
6
+
7
+ <FluxPaneBody v-html="alert.message"/>
8
+
9
+ <FluxPaneFooter>
10
+ <FluxSpacer/>
11
+
12
+ <FluxPrimaryButton
13
+ icon-leading="circle-check"
14
+ :label="translate('flux.ok')"
15
+ @click="alert.onClose()"/>
16
+ </FluxPaneFooter>
17
+ </FluxPane>
18
+ </template>
19
+
20
+ <script
21
+ lang="ts"
22
+ setup>
23
+ import type { FluxAlertObject } from '@flux-ui/types';
24
+ import { useTranslate } from '$flux/composable/private';
25
+ import FluxPane from './FluxPane.vue';
26
+ import FluxPaneBody from './FluxPaneBody.vue';
27
+ import FluxPaneFooter from './FluxPaneFooter.vue';
28
+ import FluxPaneHeader from './FluxPaneHeader.vue';
29
+ import FluxPrimaryButton from './FluxPrimaryButton.vue';
30
+ import FluxSpacer from './FluxSpacer.vue';
31
+
32
+ defineProps<{
33
+ readonly alert: FluxAlertObject;
34
+ }>();
35
+
36
+ const translate = useTranslate();
37
+ </script>
@@ -0,0 +1,141 @@
1
+ <template>
2
+ <canvas
3
+ ref="canvas"
4
+ :class="$style.animatedColors"/>
5
+ </template>
6
+
7
+ <script
8
+ lang="ts"
9
+ setup>
10
+ import { mulberry32 } from '@basmilius/utils';
11
+ import { useComponentId } from '@flux-ui/internals';
12
+ import { computed, onBeforeUnmount, onMounted, ref, unref, useTemplateRef, watch } from 'vue';
13
+ import $style from '$flux/css/component/Visual.module.scss';
14
+
15
+ type Polygon = [number, number, string, PolygonPoint[]];
16
+ type PolygonPoint = [number, number, number];
17
+
18
+ const {
19
+ colors,
20
+ incrementor = 1,
21
+ opacity = .5,
22
+ seed
23
+ } = defineProps<{
24
+ readonly colors?: string[];
25
+ readonly incrementor?: number;
26
+ readonly opacity?: number;
27
+ readonly seed?: number;
28
+ }>();
29
+
30
+ const canvasRef = useTemplateRef('canvas');
31
+ const componentId = useComponentId();
32
+
33
+ const contextRef = ref<CanvasRenderingContext2D>();
34
+ const animationFrame = ref(0);
35
+ const tick = ref(0);
36
+
37
+ const polygons = computed(() => {
38
+ if (!colors || colors.length === 0) {
39
+ return [];
40
+ }
41
+
42
+ const mulberry = mulberry32(seed ?? unref(componentId));
43
+ const polygons: Polygon[] = [];
44
+
45
+ for (const color of colors) {
46
+ const localMulberry = mulberry.fork();
47
+
48
+ const x = colors.length === 1 ? .5 : localMulberry.next();
49
+ const y = colors.length === 1 ? .5 : localMulberry.next();
50
+ const count = Math.round(localMulberry.nextBetween(6, 9));
51
+ const points: PolygonPoint[] = [];
52
+
53
+ for (let p = 0; p < count; ++p) {
54
+ points.push([
55
+ localMulberry.next(),
56
+ localMulberry.next(),
57
+ localMulberry.next()
58
+ ]);
59
+ }
60
+
61
+ polygons.push([x, y, color, points]);
62
+ }
63
+
64
+ return polygons;
65
+ });
66
+
67
+ onMounted(() => schedule());
68
+ onBeforeUnmount(() => cancel());
69
+
70
+ function cancel(): void {
71
+ cancelAnimationFrame(animationFrame.value);
72
+ }
73
+
74
+ function schedule(): void {
75
+ animationFrame.value = requestAnimationFrame(update);
76
+ tick.value += incrementor;
77
+ }
78
+
79
+ function update(): void {
80
+ const context = unref(contextRef);
81
+ const shapes = unref(polygons);
82
+
83
+ if (!context || shapes.length === 0) {
84
+ return;
85
+ }
86
+
87
+ const width = context.canvas.offsetWidth;
88
+ const height = context.canvas.offsetHeight;
89
+ context.canvas.width = width;
90
+ context.canvas.height = height;
91
+
92
+ const widthBasedOpacity = Math.min(1, Math.max(.15, 360 / width));
93
+
94
+ context.globalAlpha = opacity * widthBasedOpacity;
95
+ context.globalCompositeOperation = 'screen';
96
+ context.clearRect(0, 0, width, height);
97
+
98
+ for (const [tx, ty, color, shape] of shapes) {
99
+ context.save();
100
+ context.translate(tx * width, ty * height);
101
+ context.beginPath();
102
+ context.fillStyle = color;
103
+
104
+ for (let i = 0; i < shape.length; ++i) {
105
+ let [x, y, m] = shape[i];
106
+
107
+ x = Math.cos(x * Math.PI * 2 + tick.value / (m * 200 + 300)) * (width * .8);
108
+ y = Math.sin(y * Math.PI * 2 + tick.value / (m * 100 + 300)) * (height * .8);
109
+
110
+ if (i === 0) {
111
+ context.moveTo(x, y);
112
+ } else {
113
+ context.lineTo(x, y);
114
+ }
115
+ }
116
+
117
+ context.closePath();
118
+ context.fill();
119
+ context.restore();
120
+ }
121
+
122
+ schedule();
123
+ }
124
+
125
+ watch(canvasRef, canvas => {
126
+ if (!canvas) {
127
+ contextRef.value = undefined;
128
+ return;
129
+ }
130
+
131
+ contextRef.value = canvas.getContext('2d', {
132
+ alpha: true,
133
+ colorSpace: 'display-p3'
134
+ })!;
135
+ }, {immediate: true});
136
+
137
+ watch(polygons, () => {
138
+ cancel();
139
+ schedule();
140
+ });
141
+ </script>
@@ -0,0 +1,21 @@
1
+ <template>
2
+ <div
3
+ :class="$style.aspectRatio"
4
+ :style="{aspectRatio}">
5
+ <slot/>
6
+ </div>
7
+ </template>
8
+
9
+ <script
10
+ lang="ts"
11
+ setup>
12
+ import $style from '$flux/css/component/Layout.module.scss';
13
+
14
+ defineProps<{
15
+ aspectRatio: number;
16
+ }>();
17
+
18
+ defineSlots<{
19
+ default(): any;
20
+ }>();
21
+ </script>
@@ -0,0 +1,27 @@
1
+ <template>
2
+ <div
3
+ :class="$style.autoGrid"
4
+ :style="{
5
+ gap: `${gap}px`,
6
+ '--min-column-width': minColumnWidth
7
+ }">
8
+ <slot/>
9
+ </div>
10
+ </template>
11
+
12
+ <script
13
+ lang="ts"
14
+ setup>
15
+ import $style from '$flux/css/component/Layout.module.scss';
16
+
17
+ const {
18
+ gap = 30
19
+ } = defineProps<{
20
+ readonly gap?: number;
21
+ readonly minColumnWidth: number;
22
+ }>();
23
+
24
+ defineSlots<{
25
+ default(): any;
26
+ }>();
27
+ </script>
@@ -0,0 +1,119 @@
1
+ <template>
2
+ <FluxPressable
3
+ :class="clsx(
4
+ !status && $style.avatar,
5
+ !!status && $style.statusAvatar,
6
+ type !== 'none' && $style.avatarClickable
7
+ )"
8
+ :style="{
9
+ '--color': color,
10
+ fontSize: size && `${size}px`
11
+ }"
12
+ :component-type="type"
13
+ role="img"
14
+ :aria-label="alt"
15
+ :tabindex="tabindex"
16
+ :href="href"
17
+ :rel="rel"
18
+ :target="target"
19
+ :to="to"
20
+ @click="$emit('click', $event)"
21
+ @mouseenter="$emit('mouseenter', $event)"
22
+ @mouseleave="$emit('mouseleave', $event)">
23
+ <img
24
+ v-if="src"
25
+ :class="$style.avatarImage"
26
+ :alt="alt"
27
+ :src="src"/>
28
+
29
+ <div
30
+ v-else
31
+ :class="fallback === 'colorized' ? $style.avatarFallbackColorized : $style.avatarFallbackNeutral">
32
+ <span v-if="fallbackInitials">
33
+ {{ fallbackInitials }}
34
+ </span>
35
+
36
+ <FluxIcon
37
+ v-else-if="fallbackIcon"
38
+ :name="fallbackIcon"/>
39
+ </div>
40
+
41
+ <FluxFadeTransition>
42
+ <div
43
+ v-if="isLoading"
44
+ :class="$style.avatarLoading">
45
+ <FluxSpinner/>
46
+ </div>
47
+ </FluxFadeTransition>
48
+
49
+ <div
50
+ v-if="status"
51
+ :class="STATUS_CLASS_MAP[status]"/>
52
+ </FluxPressable>
53
+ </template>
54
+
55
+ <script
56
+ lang="ts"
57
+ setup>
58
+ import { amber600, blue600, cyan600, emerald600, fuchsia600, green600, indigo600, lime600, orange600, pink600, purple600, red600, rose600, sky600, teal600, violet600, yellow600 } from '@flux-ui/internals';
59
+ import type { FluxButtonEmits, FluxColor, FluxIconName, FluxPressableType, FluxTo } from '@flux-ui/types';
60
+ import { clsx } from 'clsx';
61
+ import { computed, unref } from 'vue';
62
+ import { FluxFadeTransition } from '$flux/transition';
63
+ import FluxIcon from './FluxIcon.vue';
64
+ import FluxPressable from './FluxPressable.vue';
65
+ import FluxSpinner from './FluxSpinner.vue';
66
+ import $style from '$flux/css/component/Avatar.module.scss';
67
+
68
+ const STATUS_CLASS_MAP = {
69
+ gray: $style.avatarStatusGray,
70
+ primary: $style.avatarStatusPrimary,
71
+ danger: $style.avatarStatusDanger,
72
+ info: $style.avatarStatusInfo,
73
+ success: $style.avatarStatusSuccess,
74
+ warning: $style.avatarStatusWarning
75
+ } as const;
76
+
77
+ defineEmits<FluxButtonEmits>();
78
+
79
+ const {
80
+ fallback = 'colorized',
81
+ fallbackColors = [lime600, green600, emerald600, teal600, cyan600, sky600, blue600, indigo600, violet600, purple600, fuchsia600, pink600, rose600, red600, orange600, amber600, yellow600],
82
+ fallbackIcon = 'user',
83
+ fallbackInitials,
84
+ type = 'none'
85
+ } = defineProps<{
86
+ readonly alt?: string;
87
+ readonly fallback?: 'colorized' | 'neutral';
88
+ readonly fallbackColors?: string[];
89
+ readonly fallbackIcon?: FluxIconName;
90
+ readonly fallbackInitials?: string;
91
+ readonly isLoading?: boolean;
92
+ readonly size?: number;
93
+ readonly src?: string;
94
+ readonly status?: FluxColor;
95
+ readonly type?: FluxPressableType;
96
+ readonly tabindex?: string | number;
97
+ readonly href?: string;
98
+ readonly rel?: string;
99
+ readonly target?: string;
100
+ readonly to?: FluxTo;
101
+ }>();
102
+
103
+ const color = computed(() => fallbackColors[unref(colorSeed) % fallbackColors.length]);
104
+ const colorSeed = computed(() => {
105
+ let seed = 6;
106
+
107
+ if (fallbackInitials) {
108
+ for (let i = 0; i < fallbackInitials.length; ++i) {
109
+ seed ^= fallbackInitials.charCodeAt(i);
110
+ }
111
+ } else if (fallbackIcon) {
112
+ for (let i = 0; i < fallbackIcon.length; ++i) {
113
+ seed ^= fallbackIcon.charCodeAt(i);
114
+ }
115
+ }
116
+
117
+ return seed;
118
+ });
119
+ </script>