@7pmlabs/design-system 2.0.9 → 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -4
- package/dist/design-system.css +1 -1
- package/dist/design-system.js +65 -59
- package/dist/design-system100.js +1 -1
- package/dist/design-system100.js.map +1 -1
- package/dist/design-system101.js +87 -53
- package/dist/design-system101.js.map +1 -1
- package/dist/design-system103.js +5 -13
- package/dist/design-system103.js.map +1 -1
- package/dist/design-system104.js +53 -108
- package/dist/design-system104.js.map +1 -1
- package/dist/{design-system102.js → design-system105.js} +1 -1
- package/dist/{design-system102.js.map → design-system105.js.map} +1 -1
- package/dist/design-system106.js +13 -6
- package/dist/design-system106.js.map +1 -1
- package/dist/design-system107.js +93 -190
- package/dist/design-system107.js.map +1 -1
- package/dist/design-system109.js +2 -2
- package/dist/design-system109.js.map +1 -1
- package/dist/design-system110.js +183 -484
- package/dist/design-system110.js.map +1 -1
- package/dist/design-system112.js +5 -4
- package/dist/design-system112.js.map +1 -1
- package/dist/design-system113.js +507 -7
- package/dist/design-system113.js.map +1 -1
- package/dist/design-system115.js +8 -0
- package/dist/design-system115.js.map +1 -0
- package/dist/design-system116.js +7 -6
- package/dist/design-system116.js.map +1 -1
- package/dist/design-system117.js +154 -169
- package/dist/design-system117.js.map +1 -1
- package/dist/design-system119.js +2 -2
- package/dist/design-system119.js.map +1 -1
- package/dist/design-system120.js +210 -149
- package/dist/design-system120.js.map +1 -1
- package/dist/design-system122.js +5 -4
- package/dist/design-system122.js.map +1 -1
- package/dist/design-system123.js +160 -9
- package/dist/design-system123.js.map +1 -1
- package/dist/design-system125.js +8 -0
- package/dist/design-system125.js.map +1 -0
- package/dist/design-system126.js +176 -6
- package/dist/design-system126.js.map +1 -1
- package/dist/design-system128.js +8 -0
- package/dist/design-system128.js.map +1 -0
- package/dist/design-system129.js +213 -5
- package/dist/design-system129.js.map +1 -1
- package/dist/design-system131.js +5 -90
- package/dist/design-system131.js.map +1 -1
- package/dist/design-system132.js +166 -0
- package/dist/design-system132.js.map +1 -0
- package/dist/design-system134.js +5 -42
- package/dist/design-system134.js.map +1 -1
- package/dist/design-system135.js +12 -0
- package/dist/design-system135.js.map +1 -0
- package/dist/design-system136.js +274 -5
- package/dist/design-system136.js.map +1 -1
- package/dist/design-system138.js +9 -0
- package/dist/{design-system124.js.map → design-system138.js.map} +1 -1
- package/dist/design-system139.js +16 -5
- package/dist/design-system139.js.map +1 -1
- package/dist/design-system141.js +8 -0
- package/dist/{design-system127.js.map → design-system141.js.map} +1 -1
- package/dist/design-system142.js +12 -5
- package/dist/design-system142.js.map +1 -1
- package/dist/design-system143.js +78 -83
- package/dist/design-system143.js.map +1 -1
- package/dist/design-system145.js +1 -1
- package/dist/design-system145.js.map +1 -1
- package/dist/design-system146.js +42 -9
- package/dist/design-system146.js.map +1 -1
- package/dist/design-system148.js +3 -2
- package/dist/design-system148.js.map +1 -1
- package/dist/design-system149.js +230 -18
- package/dist/design-system149.js.map +1 -1
- package/dist/design-system151.js +5 -158
- package/dist/design-system151.js.map +1 -1
- package/dist/{design-system140.js → design-system152.js} +6 -6
- package/dist/{design-system140.js.map → design-system152.js.map} +1 -1
- package/dist/design-system154.js +5 -307
- package/dist/design-system154.js.map +1 -1
- package/dist/design-system155.js +98 -0
- package/dist/design-system155.js.map +1 -0
- package/dist/design-system157.js +5 -240
- package/dist/design-system157.js.map +1 -1
- package/dist/design-system158.js +12 -0
- package/dist/design-system158.js.map +1 -0
- package/dist/design-system159.js +37 -5
- package/dist/design-system159.js.map +1 -1
- package/dist/design-system160.js +4 -189
- package/dist/design-system160.js.map +1 -1
- package/dist/design-system161.js +24 -0
- package/dist/{design-system150.js.map → design-system161.js.map} +1 -1
- package/dist/design-system162.js +2 -3
- package/dist/design-system162.js.map +1 -1
- package/dist/design-system163.js +158 -3
- package/dist/design-system163.js.map +1 -1
- package/dist/{design-system153.js → design-system165.js} +2 -2
- package/dist/{design-system153.js.map → design-system165.js.map} +1 -1
- package/dist/design-system166.js +307 -6
- package/dist/design-system166.js.map +1 -1
- package/dist/{design-system156.js → design-system168.js} +2 -2
- package/dist/{design-system156.js.map → design-system168.js.map} +1 -1
- package/dist/design-system169.js +167 -6
- package/dist/design-system169.js.map +1 -1
- package/dist/design-system171.js +8 -0
- package/dist/design-system171.js.map +1 -0
- package/dist/design-system172.js +240 -6
- package/dist/design-system172.js.map +1 -1
- package/dist/design-system174.js +8 -0
- package/dist/design-system174.js.map +1 -0
- package/dist/design-system175.js +189 -6
- package/dist/design-system175.js.map +1 -1
- package/dist/design-system177.js +8 -0
- package/dist/design-system177.js.map +1 -0
- package/dist/design-system178.js +3 -5
- package/dist/design-system178.js.map +1 -1
- package/dist/design-system179.js +58 -11
- package/dist/design-system179.js.map +1 -1
- package/dist/design-system181.js +9 -0
- package/dist/design-system181.js.map +1 -0
- package/dist/design-system182.js +56 -6
- package/dist/design-system182.js.map +1 -1
- package/dist/design-system184.js +9 -0
- package/dist/{design-system167.js.map → design-system184.js.map} +1 -1
- package/dist/design-system185.js +69 -5
- package/dist/design-system185.js.map +1 -1
- package/dist/design-system187.js +9 -0
- package/dist/{design-system170.js.map → design-system187.js.map} +1 -1
- package/dist/design-system188.js +182 -5
- package/dist/design-system188.js.map +1 -1
- package/dist/design-system190.js +9 -0
- package/dist/design-system190.js.map +1 -0
- package/dist/design-system191.js +115 -5
- package/dist/design-system191.js.map +1 -1
- package/dist/design-system193.js +8 -0
- package/dist/{design-system176.js.map → design-system193.js.map} +1 -1
- package/dist/design-system194.js +11 -5
- package/dist/design-system194.js.map +1 -1
- package/dist/design-system195.js +453 -24
- package/dist/design-system195.js.map +1 -1
- package/dist/design-system197.js +5 -4
- package/dist/design-system197.js.map +1 -1
- package/dist/design-system198.js +20 -16
- package/dist/design-system198.js.map +1 -1
- package/dist/design-system200.js +1 -1
- package/dist/design-system200.js.map +1 -1
- package/dist/design-system201.js +70 -314
- package/dist/design-system201.js.map +1 -1
- package/dist/design-system203.js +1 -1
- package/dist/design-system203.js.map +1 -1
- package/dist/design-system204.js +24 -89
- package/dist/design-system204.js.map +1 -1
- package/dist/design-system206.js +1 -1
- package/dist/design-system206.js.map +1 -1
- package/dist/design-system207.js +26 -17
- package/dist/design-system207.js.map +1 -1
- package/dist/design-system209.js +5 -3
- package/dist/design-system209.js.map +1 -1
- package/dist/design-system210.js +22 -408
- package/dist/design-system210.js.map +1 -1
- package/dist/design-system212.js +1 -1
- package/dist/design-system212.js.map +1 -1
- package/dist/design-system213.js +24 -52
- package/dist/design-system213.js.map +1 -1
- package/dist/design-system215.js +1 -1
- package/dist/design-system215.js.map +1 -1
- package/dist/design-system216.js +329 -85
- package/dist/design-system216.js.map +1 -1
- package/dist/design-system218.js +5 -108
- package/dist/design-system218.js.map +1 -1
- package/dist/design-system219.js +103 -0
- package/dist/design-system219.js.map +1 -0
- package/dist/design-system221.js +5 -106
- package/dist/design-system221.js.map +1 -1
- package/dist/design-system222.js +22 -0
- package/dist/{design-system208.js.map → design-system222.js.map} +1 -1
- package/dist/design-system223.js +4 -6
- package/dist/design-system223.js.map +1 -1
- package/dist/design-system224.js +3 -737
- package/dist/design-system224.js.map +1 -1
- package/dist/design-system225.js +422 -0
- package/dist/design-system225.js.map +1 -0
- package/dist/design-system227.js +5 -11
- package/dist/design-system227.js.map +1 -1
- package/dist/design-system228.js +51 -517
- package/dist/design-system228.js.map +1 -1
- package/dist/design-system230.js +1 -1
- package/dist/design-system230.js.map +1 -1
- package/dist/design-system231.js +88 -3
- package/dist/design-system231.js.map +1 -1
- package/dist/design-system232.js +4 -46
- package/dist/design-system232.js.map +1 -1
- package/dist/design-system233.js +108 -4
- package/dist/design-system233.js.map +1 -1
- package/dist/{design-system220.js → design-system235.js} +2 -2
- package/dist/{design-system220.js.map → design-system235.js.map} +1 -1
- package/dist/design-system236.js +106 -5
- package/dist/design-system236.js.map +1 -1
- package/dist/design-system238.js +9 -0
- package/dist/design-system238.js.map +1 -0
- package/dist/design-system239.js +737 -5
- package/dist/design-system239.js.map +1 -1
- package/dist/{design-system226.js → design-system241.js} +2 -2
- package/dist/{design-system226.js.map → design-system241.js.map} +1 -1
- package/dist/design-system242.js +3 -5
- package/dist/design-system242.js.map +1 -1
- package/dist/design-system243.js +42 -50
- package/dist/design-system243.js.map +1 -1
- package/dist/design-system244.js +1 -1
- package/dist/design-system244.js.map +1 -1
- package/dist/design-system245.js +254 -141
- package/dist/design-system245.js.map +1 -1
- package/dist/design-system247.js +1 -1
- package/dist/design-system247.js.map +1 -1
- package/dist/design-system248.js +119 -7
- package/dist/design-system248.js.map +1 -1
- package/dist/design-system250.js +8 -0
- package/dist/design-system250.js.map +1 -0
- package/dist/design-system251.js +172 -5
- package/dist/design-system251.js.map +1 -1
- package/dist/design-system253.js +8 -0
- package/dist/design-system253.js.map +1 -0
- package/dist/design-system254.js +11 -6
- package/dist/design-system254.js.map +1 -1
- package/dist/design-system255.js +525 -9
- package/dist/design-system255.js.map +1 -1
- package/dist/design-system257.js +8 -0
- package/dist/design-system257.js.map +1 -0
- package/dist/design-system258.js +112 -6
- package/dist/design-system258.js.map +1 -1
- package/dist/design-system260.js +5 -374
- package/dist/design-system260.js.map +1 -1
- package/dist/design-system261.js +57 -0
- package/dist/design-system261.js.map +1 -0
- package/dist/design-system262.js +4 -6
- package/dist/design-system262.js.map +1 -1
- package/dist/design-system263.js +173 -0
- package/dist/design-system263.js.map +1 -0
- package/dist/design-system265.js +8 -0
- package/dist/design-system265.js.map +1 -0
- package/dist/design-system266.js +10 -0
- package/dist/design-system266.js.map +1 -0
- package/dist/{design-system249.js → design-system267.js} +2 -2
- package/dist/{design-system249.js.map → design-system267.js.map} +1 -1
- package/dist/design-system269.js +8 -0
- package/dist/design-system269.js.map +1 -0
- package/dist/{design-system252.js → design-system270.js} +1 -1
- package/dist/{design-system252.js.map → design-system270.js.map} +1 -1
- package/dist/design-system272.js +9 -0
- package/dist/design-system272.js.map +1 -0
- package/dist/design-system273.js +12 -0
- package/dist/design-system273.js.map +1 -0
- package/dist/{design-system256.js → design-system274.js} +2 -2
- package/dist/{design-system256.js.map → design-system274.js.map} +1 -1
- package/dist/design-system276.js +9 -0
- package/dist/design-system276.js.map +1 -0
- package/dist/{design-system259.js → design-system277.js} +1 -1
- package/dist/{design-system259.js.map → design-system277.js.map} +1 -1
- package/dist/design-system278.js +377 -0
- package/dist/design-system278.js.map +1 -0
- package/dist/design-system280.js +9 -0
- package/dist/design-system280.js.map +1 -0
- package/dist/design-system69.js +182 -13
- package/dist/design-system69.js.map +1 -1
- package/dist/design-system71.js +8 -0
- package/dist/design-system71.js.map +1 -0
- package/dist/design-system72.js +13 -5
- package/dist/design-system72.js.map +1 -1
- package/dist/design-system73.js +677 -139
- package/dist/design-system73.js.map +1 -1
- package/dist/design-system75.js +1 -1
- package/dist/design-system75.js.map +1 -1
- package/dist/design-system76.js +152 -23
- package/dist/design-system76.js.map +1 -1
- package/dist/design-system78.js +5 -49
- package/dist/design-system78.js.map +1 -1
- package/dist/design-system79.js +32 -0
- package/dist/design-system79.js.map +1 -0
- package/dist/design-system80.js +2 -3
- package/dist/design-system80.js.map +1 -1
- package/dist/design-system81.js +38 -188
- package/dist/design-system81.js.map +1 -1
- package/dist/design-system83.js +1 -1
- package/dist/design-system83.js.map +1 -1
- package/dist/design-system84.js +199 -7
- package/dist/design-system84.js.map +1 -1
- package/dist/design-system86.js +8 -0
- package/dist/design-system86.js.map +1 -0
- package/dist/design-system87.js +7 -5
- package/dist/design-system87.js.map +1 -1
- package/dist/design-system88.js +264 -48
- package/dist/design-system88.js.map +1 -1
- package/dist/design-system90.js +1 -1
- package/dist/design-system90.js.map +1 -1
- package/dist/design-system91.js +57 -11
- package/dist/design-system91.js.map +1 -1
- package/dist/design-system93.js +8 -0
- package/dist/design-system93.js.map +1 -0
- package/dist/design-system94.js +11 -5
- package/dist/design-system94.js.map +1 -1
- package/dist/design-system95.js +92 -59
- package/dist/design-system95.js.map +1 -1
- package/dist/design-system97.js +1 -1
- package/dist/design-system97.js.map +1 -1
- package/dist/design-system98.js +56 -78
- package/dist/design-system98.js.map +1 -1
- package/dist/types/components/BContextMenu/BContextMenu.spec.d.ts +1 -0
- package/dist/types/components/BContextMenu/BContextMenu.vue.d.ts +42 -0
- package/dist/types/components/BContextMenu/index.d.ts +2 -0
- package/dist/types/components/BContextMenu/types.d.ts +23 -0
- package/dist/types/components/BInputTags/BInputTags.spec.d.ts +1 -0
- package/dist/types/components/BInputTags/BInputTags.vue.d.ts +54 -0
- package/dist/types/components/BInputTags/index.d.ts +1 -0
- package/dist/types/components/BLink/BLink.spec.d.ts +1 -0
- package/dist/types/components/BLink/BLink.vue.d.ts +100 -0
- package/dist/types/components/BLink/index.d.ts +1 -0
- package/dist/types/components/BListbox/BListbox.spec.d.ts +1 -0
- package/dist/types/components/BListbox/BListbox.vue.d.ts +52 -0
- package/dist/types/components/BListbox/index.d.ts +1 -0
- package/dist/types/components/BModal/BModal.spec.d.ts +1 -0
- package/dist/types/components/BPinInput/BPinInput.spec.d.ts +1 -0
- package/dist/types/components/BPinInput/BPinInput.vue.d.ts +43 -0
- package/dist/types/components/BPinInput/index.d.ts +1 -0
- package/dist/types/components/BProgress/BProgress.vue.d.ts +47 -2
- package/dist/types/components/BTextarea/BTextarea.spec.d.ts +1 -0
- package/dist/types/components/BTextarea/BTextarea.vue.d.ts +77 -0
- package/dist/types/components/BTextarea/index.d.ts +1 -0
- package/dist/types/components/index.d.ts +7 -1
- package/package.json +1 -1
- package/dist/design-system114.js +0 -212
- package/dist/design-system114.js.map +0 -1
- package/dist/design-system124.js +0 -277
- package/dist/design-system127.js +0 -19
- package/dist/design-system130.js +0 -15
- package/dist/design-system130.js.map +0 -1
- package/dist/design-system133.js +0 -8
- package/dist/design-system133.js.map +0 -1
- package/dist/design-system137.js +0 -236
- package/dist/design-system137.js.map +0 -1
- package/dist/design-system147.js +0 -40
- package/dist/design-system147.js.map +0 -1
- package/dist/design-system150.js +0 -7
- package/dist/design-system164.js +0 -61
- package/dist/design-system164.js.map +0 -1
- package/dist/design-system167.js +0 -59
- package/dist/design-system170.js +0 -72
- package/dist/design-system173.js +0 -185
- package/dist/design-system173.js.map +0 -1
- package/dist/design-system176.js +0 -118
- package/dist/design-system180.js +0 -465
- package/dist/design-system180.js.map +0 -1
- package/dist/design-system183.js +0 -38
- package/dist/design-system183.js.map +0 -1
- package/dist/design-system186.js +0 -91
- package/dist/design-system186.js.map +0 -1
- package/dist/design-system189.js +0 -38
- package/dist/design-system189.js.map +0 -1
- package/dist/design-system192.js +0 -31
- package/dist/design-system192.js.map +0 -1
- package/dist/design-system208.js +0 -7
- package/dist/design-system217.js +0 -7
- package/dist/design-system217.js.map +0 -1
- package/dist/design-system234.js +0 -286
- package/dist/design-system234.js.map +0 -1
- package/dist/design-system237.js +0 -122
- package/dist/design-system237.js.map +0 -1
- package/dist/design-system240.js +0 -115
- package/dist/design-system240.js.map +0 -1
- package/dist/design-system70.js +0 -699
- package/dist/design-system70.js.map +0 -1
- package/dist/design-system77.js +0 -7
- package/dist/design-system77.js.map +0 -1
- package/dist/design-system85.js +0 -276
- package/dist/design-system85.js.map +0 -1
- package/dist/design-system92.js +0 -102
- package/dist/design-system92.js.map +0 -1
package/dist/design-system69.js
CHANGED
|
@@ -1,16 +1,185 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
1
|
+
import { useComponentId as e } from "./design-system10.js";
|
|
2
|
+
import t from "./design-system27.js";
|
|
3
|
+
import { Fragment as n, Teleport as r, Transition as i, computed as a, createBlock as o, createCommentVNode as s, createElementBlock as c, createElementVNode as l, createVNode as u, defineComponent as d, nextTick as f, normalizeClass as p, normalizeStyle as m, onBeforeUnmount as h, openBlock as g, ref as _, renderList as v, renderSlot as y, toDisplayString as b, watch as x, withCtx as S, withModifiers as C } from "vue";
|
|
4
|
+
//#region src/components/BContextMenu/BContextMenu.vue?vue&type=script&setup=true&lang.ts
|
|
5
|
+
var w = [
|
|
6
|
+
"id",
|
|
7
|
+
"aria-label",
|
|
8
|
+
"aria-activedescendant"
|
|
9
|
+
], T = {
|
|
10
|
+
key: 0,
|
|
11
|
+
role: "separator",
|
|
12
|
+
"aria-hidden": "true",
|
|
13
|
+
class: "b-context-menu__divider-row"
|
|
14
|
+
}, E = [
|
|
15
|
+
"id",
|
|
16
|
+
"aria-disabled",
|
|
17
|
+
"onClick",
|
|
18
|
+
"onMouseenter"
|
|
19
|
+
], D = {
|
|
20
|
+
key: 0,
|
|
21
|
+
class: "b-context-menu__item-icon",
|
|
22
|
+
"aria-hidden": "true"
|
|
23
|
+
}, O = { class: "b-context-menu__item-label" }, k = /* @__PURE__ */ d({
|
|
24
|
+
__name: "BContextMenu",
|
|
25
|
+
props: {
|
|
26
|
+
items: {},
|
|
27
|
+
disabled: {
|
|
28
|
+
type: Boolean,
|
|
29
|
+
default: !1
|
|
30
|
+
},
|
|
31
|
+
id: {},
|
|
32
|
+
ariaLabel: { default: "Context menu" }
|
|
33
|
+
},
|
|
34
|
+
emits: [
|
|
35
|
+
"select",
|
|
36
|
+
"open",
|
|
37
|
+
"close"
|
|
38
|
+
],
|
|
39
|
+
setup(d, { expose: k, emit: A }) {
|
|
40
|
+
let j = A, { componentUID: M } = e(), N = a(() => d.id ?? `b-context-menu-${M.value}`), P = (e) => `${N.value}-item-${e}`, F = _(!1), I = _(0), L = _(0), R = _(-1), z = _(null), B = null, V = (e) => !e.divider && !e.disabled, H = () => d.items.findIndex(V), U = () => {
|
|
41
|
+
for (let e = d.items.length - 1; e >= 0; e--) if (V(d.items[e])) return e;
|
|
42
|
+
return -1;
|
|
43
|
+
}, W = (e) => {
|
|
44
|
+
if (d.items.length === 0) return;
|
|
45
|
+
let t = d.items.length, n = R.value;
|
|
46
|
+
for (let r = 0; r < t; r++) if (n = ((n + e) % t + t) % t, V(d.items[n])) {
|
|
47
|
+
R.value = n;
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
}, G = (e) => {
|
|
51
|
+
e < 0 || e >= d.items.length || V(d.items[e]) && (R.value = e);
|
|
52
|
+
}, K = a(() => R.value >= 0 ? P(R.value) : void 0), q = (e) => {
|
|
53
|
+
d.disabled || J(e.clientX, e.clientY, e);
|
|
54
|
+
}, J = (e, t, n) => {
|
|
55
|
+
typeof document < "u" && (B = document.activeElement ?? null), I.value = e, L.value = t, R.value = H(), F.value = !0, j("open", n ?? (typeof MouseEvent < "u" ? new MouseEvent("contextmenu", {
|
|
56
|
+
clientX: e,
|
|
57
|
+
clientY: t
|
|
58
|
+
}) : {
|
|
59
|
+
clientX: e,
|
|
60
|
+
clientY: t
|
|
61
|
+
}));
|
|
62
|
+
}, Y = () => {
|
|
63
|
+
F.value && (F.value = !1, j("close"));
|
|
64
|
+
};
|
|
65
|
+
k({
|
|
66
|
+
open: (e, t) => {
|
|
67
|
+
J(e, t);
|
|
68
|
+
},
|
|
69
|
+
close: Y
|
|
70
|
+
});
|
|
71
|
+
let X = () => {
|
|
72
|
+
if (typeof window > "u") return;
|
|
73
|
+
let e = z.value;
|
|
74
|
+
if (!e) return;
|
|
75
|
+
let t = e.getBoundingClientRect(), n = window.innerWidth || 0, r = window.innerHeight || 0, i = I.value, a = L.value;
|
|
76
|
+
i + t.width > n && (i = Math.max(0, i - t.width)), a + t.height > r && (a = Math.max(0, a - t.height)), I.value = i, L.value = a;
|
|
77
|
+
};
|
|
78
|
+
x(F, async (e) => {
|
|
79
|
+
if (e) await f(), X(), z.value?.focus(), typeof document < "u" && document.addEventListener("mousedown", Z, !0);
|
|
80
|
+
else {
|
|
81
|
+
if (typeof document < "u" && document.removeEventListener("mousedown", Z, !0), R.value = -1, B && typeof B.focus == "function") try {
|
|
82
|
+
B.focus();
|
|
83
|
+
} catch {}
|
|
84
|
+
B = null;
|
|
85
|
+
}
|
|
86
|
+
});
|
|
87
|
+
let Z = (e) => {
|
|
88
|
+
if (!F.value) return;
|
|
89
|
+
let t = e.target;
|
|
90
|
+
t && z.value && z.value.contains(t) || Y();
|
|
91
|
+
}, Q = (e, t) => {
|
|
92
|
+
if (!(e.divider || e.disabled)) try {
|
|
93
|
+
e.onSelect?.();
|
|
94
|
+
} finally {
|
|
95
|
+
j("select", e, t), Y();
|
|
96
|
+
}
|
|
97
|
+
}, $ = (e, t, n) => {
|
|
98
|
+
e.divider || e.disabled || (G(t), Q(e, n));
|
|
99
|
+
}, ee = (e, t) => {
|
|
100
|
+
e.divider || e.disabled || (R.value = t);
|
|
101
|
+
}, te = (e) => {
|
|
102
|
+
switch (e.key) {
|
|
103
|
+
case "ArrowDown":
|
|
104
|
+
e.preventDefault(), W(1);
|
|
105
|
+
break;
|
|
106
|
+
case "ArrowUp":
|
|
107
|
+
e.preventDefault(), W(-1);
|
|
108
|
+
break;
|
|
109
|
+
case "Home":
|
|
110
|
+
e.preventDefault(), G(H());
|
|
111
|
+
break;
|
|
112
|
+
case "End":
|
|
113
|
+
e.preventDefault(), G(U());
|
|
114
|
+
break;
|
|
115
|
+
case "Enter":
|
|
116
|
+
case " ": {
|
|
117
|
+
e.preventDefault();
|
|
118
|
+
let t = R.value;
|
|
119
|
+
if (t >= 0 && t < d.items.length) {
|
|
120
|
+
let n = d.items[t];
|
|
121
|
+
V(n) && Q(n, e);
|
|
122
|
+
}
|
|
123
|
+
break;
|
|
124
|
+
}
|
|
125
|
+
case "Escape":
|
|
126
|
+
e.preventDefault(), Y();
|
|
127
|
+
break;
|
|
128
|
+
case "Tab":
|
|
129
|
+
Y();
|
|
130
|
+
break;
|
|
131
|
+
}
|
|
132
|
+
};
|
|
133
|
+
h(() => {
|
|
134
|
+
typeof document < "u" && document.removeEventListener("mousedown", Z, !0);
|
|
135
|
+
}), x(() => d.items.length, (e) => {
|
|
136
|
+
F.value && R.value >= e && (R.value = H());
|
|
137
|
+
});
|
|
138
|
+
let ne = a(() => ({
|
|
139
|
+
top: `${L.value}px`,
|
|
140
|
+
left: `${I.value}px`
|
|
141
|
+
}));
|
|
142
|
+
return (e, a) => (g(), c("div", {
|
|
143
|
+
class: "b-context-menu",
|
|
144
|
+
onContextmenu: C(q, ["prevent"])
|
|
145
|
+
}, [y(e.$slots, "default"), (g(), o(r, { to: "body" }, [u(i, { name: "b-context-menu-fade" }, {
|
|
146
|
+
default: S(() => [F.value ? (g(), c("ul", {
|
|
147
|
+
key: 0,
|
|
148
|
+
ref_key: "menuRef",
|
|
149
|
+
ref: z,
|
|
150
|
+
id: N.value,
|
|
151
|
+
role: "menu",
|
|
152
|
+
"aria-orientation": "vertical",
|
|
153
|
+
"aria-label": d.ariaLabel,
|
|
154
|
+
"aria-activedescendant": K.value,
|
|
155
|
+
tabindex: "-1",
|
|
156
|
+
class: "b-context-menu__list",
|
|
157
|
+
style: m(ne.value),
|
|
158
|
+
onKeydown: te
|
|
159
|
+
}, [(g(!0), c(n, null, v(d.items, (r, i) => (g(), c(n, { key: r.key }, [r.divider ? (g(), c("li", T, [...a[0] ||= [l("hr", { class: "b-context-menu__divider" }, null, -1)]])) : (g(), c("li", {
|
|
160
|
+
key: 1,
|
|
161
|
+
id: P(i),
|
|
162
|
+
role: "menuitem",
|
|
163
|
+
"aria-disabled": !!r.disabled,
|
|
164
|
+
class: p(["b-context-menu__item", {
|
|
165
|
+
"b-context-menu__item--active": R.value === i,
|
|
166
|
+
"b-context-menu__item--disabled": r.disabled,
|
|
167
|
+
"b-context-menu__item--danger": r.danger
|
|
168
|
+
}]),
|
|
169
|
+
onClick: (e) => $(r, i, e),
|
|
170
|
+
onMouseenter: (e) => ee(r, i)
|
|
171
|
+
}, [y(e.$slots, "item", {
|
|
172
|
+
item: r,
|
|
173
|
+
active: R.value === i
|
|
174
|
+
}, () => [r.icon ? (g(), c("span", D, [u(t, {
|
|
175
|
+
icon: r.icon,
|
|
176
|
+
size: "sm"
|
|
177
|
+
}, null, 8, ["icon"])])) : s("", !0), l("span", O, b(r.label), 1)])], 42, E))], 64))), 128))], 44, w)) : s("", !0)]),
|
|
178
|
+
_: 3
|
|
179
|
+
})]))], 32));
|
|
180
|
+
}
|
|
181
|
+
});
|
|
13
182
|
//#endregion
|
|
14
|
-
export {
|
|
183
|
+
export { k as default };
|
|
15
184
|
|
|
16
185
|
//# sourceMappingURL=design-system69.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"design-system69.js","names":[],"sources":["../src/components/BDatePicker/types.ts"],"sourcesContent":["export enum BDatePickerType {\n Date = 'date',\n Week = 'week',\n Month = 'month',\n Quarter = 'quarter',\n Year = 'year',\n}\n\nexport enum BDatePickerSize {\n Small = 'sm',\n Medium = 'md',\n Large = 'lg',\n}\n\nexport enum BDatePickerVariant {\n Outlined = 'outlined',\n Filled = 'filled',\n Borderless = 'borderless',\n Underlined = 'underlined',\n}\n\nexport enum BDatePickerStatus {\n Error = 'error',\n Warning = 'warning',\n}\n\nexport enum BDatePickerPlacement {\n BottomLeft = 'bottom-left',\n BottomRight = 'bottom-right',\n TopLeft = 'top-left',\n TopRight = 'top-right',\n}\n\nexport interface BDatePickerPreset {\n label: string;\n value: Date | (() => Date);\n}\n\nexport interface BDatePickerDisabledDateInfo {\n type: `${BDatePickerType}`;\n}\n"],"mappings":";AAAA,IAAY,IAAL,yBAAA,GAAA;QACL,EAAA,OAAA,QACA,EAAA,OAAA,QACA,EAAA,QAAA,SACA,EAAA,UAAA,WACA,EAAA,OAAA;KACD,EAEW,IAAL,yBAAA,GAAA;QACL,EAAA,QAAA,MACA,EAAA,SAAA,MACA,EAAA,QAAA;KACD,EAEW,IAAL,yBAAA,GAAA;QACL,EAAA,WAAA,YACA,EAAA,SAAA,UACA,EAAA,aAAA,cACA,EAAA,aAAA;KACD,EAEW,IAAL,yBAAA,GAAA;QACL,EAAA,QAAA,SACA,EAAA,UAAA;KACD,EAEW,IAAL,yBAAA,GAAA;QACL,EAAA,aAAA,eACA,EAAA,cAAA,gBACA,EAAA,UAAA,YACA,EAAA,WAAA;KACD"}
|
|
1
|
+
{"version":3,"file":"design-system69.js","names":[],"sources":["../src/components/BContextMenu/BContextMenu.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport BIcon from '@/components/BIcon/BIcon.vue';\nimport type { BIconBrandName, BIconName } from '@/components/BIcon/BIconEnum.ts';\nimport { useComponentId } from '@/composables/useComponentId.ts';\nimport { computed, nextTick, onBeforeUnmount, ref, watch } from 'vue';\nimport type { BContextMenuItem } from './types.ts';\n\nconst {\n items,\n disabled = false,\n id: idProp,\n ariaLabel = 'Context menu',\n} = defineProps<{\n /** Items to render. Each item is either a regular entry (with `label`) or a divider (`{ divider: true, key }`). */\n items: BContextMenuItem[];\n /** When true, the trigger area ignores `contextmenu` events — the menu cannot be opened. @default false */\n disabled?: boolean;\n /** Optional explicit `id` for the menu element. Falls back to a per-instance auto-generated id. */\n id?: string;\n /** Accessible label announced when the menu opens. @default 'Context menu' */\n ariaLabel?: string;\n}>();\n\nconst emit = defineEmits<{\n /** Emitted when an item is activated (click or Enter/Space). Not emitted for dividers or disabled items. */\n select: [item: BContextMenuItem, event: Event];\n /** Emitted when the menu opens via `contextmenu` (or `open()`). */\n open: [event: MouseEvent];\n /** Emitted when the menu closes. */\n close: [];\n}>();\n\ndefineSlots<{\n /** The trigger area. The component listens for `contextmenu` on the wrapping element. */\n default?(): unknown;\n /** Optional per-item override. Receives `{ item, active }`. */\n item?(props: { item: BContextMenuItem; active: boolean }): unknown;\n}>();\n\n// ── Identity ────────────────────────────────────────────────────────────────\nconst { componentUID } = useComponentId();\nconst baseId = computed(() => idProp ?? `b-context-menu-${componentUID.value}`);\nconst optionId = (i: number) => `${baseId.value}-item-${i}`;\n\n// ── State ───────────────────────────────────────────────────────────────────\nconst isOpen = ref(false);\nconst x = ref(0);\nconst y = ref(0);\nconst activeIndex = ref(-1);\nconst menuRef = ref<HTMLUListElement | null>(null);\nlet previouslyFocused: HTMLElement | null = null;\n\n// ── Activatable items (skip dividers + disabled) ────────────────────────────\nconst isActivatable = (item: BContextMenuItem): boolean =>\n !item.divider && !item.disabled;\n\nconst firstActivatableIndex = (): number => items.findIndex(isActivatable);\nconst lastActivatableIndex = (): number => {\n for (let i = items.length - 1; i >= 0; i--) {\n if (isActivatable(items[i]!)) return i;\n }\n return -1;\n};\n\nconst moveActive = (delta: number) => {\n if (items.length === 0) return;\n const len = items.length;\n let next = activeIndex.value;\n for (let step = 0; step < len; step++) {\n next = ((next + delta) % len + len) % len;\n if (isActivatable(items[next]!)) {\n activeIndex.value = next;\n return;\n }\n }\n};\n\nconst setActiveByIndex = (idx: number) => {\n if (idx < 0 || idx >= items.length) return;\n if (isActivatable(items[idx]!)) {\n activeIndex.value = idx;\n }\n};\n\nconst activeId = computed(() =>\n activeIndex.value >= 0 ? optionId(activeIndex.value) : undefined,\n);\n\n// ── Open / close ────────────────────────────────────────────────────────────\nconst handleContextMenu = (event: MouseEvent) => {\n if (disabled) return;\n openAt(event.clientX, event.clientY, event);\n};\n\nconst openAt = (px: number, py: number, event?: MouseEvent) => {\n if (typeof document !== 'undefined') {\n previouslyFocused = (document.activeElement as HTMLElement | null) ?? null;\n }\n x.value = px;\n y.value = py;\n activeIndex.value = firstActivatableIndex();\n isOpen.value = true;\n // Synthesize a MouseEvent-like object if called programmatically.\n const evt =\n event ??\n (typeof MouseEvent !== 'undefined'\n ? new MouseEvent('contextmenu', { clientX: px, clientY: py })\n : ({ clientX: px, clientY: py } as MouseEvent));\n emit('open', evt);\n};\n\nconst close = () => {\n if (!isOpen.value) return;\n isOpen.value = false;\n emit('close');\n};\n\n// Public API.\nconst openProgrammatic = (px: number, py: number) => {\n openAt(px, py);\n};\n\ndefineExpose({\n /** Open the menu programmatically at viewport coordinates. */\n open: openProgrammatic,\n /** Close the menu programmatically. */\n close,\n});\n\n// ── Position clamping & focus ───────────────────────────────────────────────\nconst clampPosition = () => {\n if (typeof window === 'undefined') return;\n const el = menuRef.value;\n if (!el) return;\n const rect = el.getBoundingClientRect();\n const vw = window.innerWidth || 0;\n const vh = window.innerHeight || 0;\n let nx = x.value;\n let ny = y.value;\n if (nx + rect.width > vw) {\n nx = Math.max(0, nx - rect.width);\n }\n if (ny + rect.height > vh) {\n ny = Math.max(0, ny - rect.height);\n }\n x.value = nx;\n y.value = ny;\n};\n\nwatch(isOpen, async (open) => {\n if (open) {\n await nextTick();\n clampPosition();\n menuRef.value?.focus();\n if (typeof document !== 'undefined') {\n document.addEventListener('mousedown', onDocumentMouseDown, true);\n }\n } else {\n if (typeof document !== 'undefined') {\n document.removeEventListener('mousedown', onDocumentMouseDown, true);\n }\n activeIndex.value = -1;\n if (previouslyFocused && typeof previouslyFocused.focus === 'function') {\n try {\n previouslyFocused.focus();\n } catch {\n // ignore — element may have been removed\n }\n }\n previouslyFocused = null;\n }\n});\n\n// ── Click-outside ───────────────────────────────────────────────────────────\nconst onDocumentMouseDown = (event: MouseEvent) => {\n if (!isOpen.value) return;\n const target = event.target as Node | null;\n if (target && menuRef.value && menuRef.value.contains(target)) return;\n close();\n};\n\n// ── Selection ───────────────────────────────────────────────────────────────\nconst selectItem = (item: BContextMenuItem, event: Event) => {\n if (item.divider || item.disabled) return;\n try {\n item.onSelect?.();\n } finally {\n emit('select', item, event);\n close();\n }\n};\n\nconst onItemClick = (item: BContextMenuItem, idx: number, event: MouseEvent) => {\n if (item.divider || item.disabled) return;\n setActiveByIndex(idx);\n selectItem(item, event);\n};\n\nconst onItemMouseEnter = (item: BContextMenuItem, idx: number) => {\n if (item.divider || item.disabled) return;\n activeIndex.value = idx;\n};\n\n// ── Keyboard ────────────────────────────────────────────────────────────────\nconst onKeyDown = (event: KeyboardEvent) => {\n switch (event.key) {\n case 'ArrowDown':\n event.preventDefault();\n moveActive(1);\n break;\n case 'ArrowUp':\n event.preventDefault();\n moveActive(-1);\n break;\n case 'Home':\n event.preventDefault();\n setActiveByIndex(firstActivatableIndex());\n break;\n case 'End':\n event.preventDefault();\n setActiveByIndex(lastActivatableIndex());\n break;\n case 'Enter':\n case ' ': {\n event.preventDefault();\n const idx = activeIndex.value;\n if (idx >= 0 && idx < items.length) {\n const item = items[idx]!;\n if (isActivatable(item)) {\n selectItem(item, event);\n }\n }\n break;\n }\n case 'Escape':\n event.preventDefault();\n close();\n break;\n case 'Tab':\n // Close — let Tab focus traversal continue naturally.\n close();\n break;\n }\n};\n\n// ── Cleanup ─────────────────────────────────────────────────────────────────\nonBeforeUnmount(() => {\n if (typeof document !== 'undefined') {\n document.removeEventListener('mousedown', onDocumentMouseDown, true);\n }\n});\n\n// Reset the active index if items shrink while open.\nwatch(\n () => items.length,\n (len) => {\n if (!isOpen.value) return;\n if (activeIndex.value >= len) {\n activeIndex.value = firstActivatableIndex();\n }\n },\n);\n\nconst menuStyle = computed(() => ({\n top: `${y.value}px`,\n left: `${x.value}px`,\n}));\n</script>\n\n<template>\n <div class=\"b-context-menu\" @contextmenu.prevent=\"handleContextMenu\">\n <slot />\n\n <Teleport to=\"body\">\n <Transition name=\"b-context-menu-fade\">\n <ul\n v-if=\"isOpen\"\n ref=\"menuRef\"\n :id=\"baseId\"\n role=\"menu\"\n aria-orientation=\"vertical\"\n :aria-label=\"ariaLabel\"\n :aria-activedescendant=\"activeId\"\n tabindex=\"-1\"\n class=\"b-context-menu__list\"\n :style=\"menuStyle\"\n @keydown=\"onKeyDown\"\n >\n <template v-for=\"(item, i) in items\" :key=\"item.key\">\n <li\n v-if=\"item.divider\"\n role=\"separator\"\n aria-hidden=\"true\"\n class=\"b-context-menu__divider-row\"\n >\n <hr class=\"b-context-menu__divider\" />\n </li>\n <li\n v-else\n :id=\"optionId(i)\"\n role=\"menuitem\"\n :aria-disabled=\"!!item.disabled\"\n :class=\"[\n 'b-context-menu__item',\n {\n 'b-context-menu__item--active': activeIndex === i,\n 'b-context-menu__item--disabled': item.disabled,\n 'b-context-menu__item--danger': item.danger,\n },\n ]\"\n @click=\"onItemClick(item, i, $event)\"\n @mouseenter=\"onItemMouseEnter(item, i)\"\n >\n <slot name=\"item\" :item=\"item\" :active=\"activeIndex === i\">\n <span\n v-if=\"item.icon\"\n class=\"b-context-menu__item-icon\"\n aria-hidden=\"true\"\n >\n <BIcon :icon=\"(item.icon as `${BIconName}` | `${BIconBrandName}`)\" size=\"sm\" />\n </span>\n <span class=\"b-context-menu__item-label\">{{ item.label }}</span>\n </slot>\n </li>\n </template>\n </ul>\n </Transition>\n </Teleport>\n </div>\n</template>\n\n<style>\n.b-context-menu {\n /* Trigger wrapper — also defines the tokens so consumers can override on the wrapper. */\n --b-context-menu-bg: oklch(100% 0 0);\n --b-context-menu-fg: oklch(20% 0.005 286);\n --b-context-menu-border-color: oklch(92% 0.004 286.32);\n --b-context-menu-radius: 8px;\n --b-context-menu-shadow:\n 0 6px 16px 0 oklch(0% 0 0 / 0.08),\n 0 3px 6px -4px oklch(0% 0 0 / 0.12),\n 0 9px 28px 8px oklch(0% 0 0 / 0.05);\n --b-context-menu-padding: 4px;\n --b-context-menu-min-width: 180px;\n --b-context-menu-item-padding-x: 12px;\n --b-context-menu-item-padding-y: 6px;\n --b-context-menu-item-bg-hover: oklch(96% 0.003 286);\n --b-context-menu-item-bg-active: oklch(94% 0.02 240);\n --b-context-menu-item-fg-disabled: oklch(70% 0.005 286);\n --b-context-menu-item-fg-danger: oklch(55% 0.22 25.331);\n --b-context-menu-divider-color: oklch(92% 0.004 286.32);\n}\n\n/* The list is teleported to <body> — re-declare tokens on its root so they resolve. */\n.b-context-menu__list {\n --b-context-menu-bg: oklch(100% 0 0);\n --b-context-menu-fg: oklch(20% 0.005 286);\n --b-context-menu-border-color: oklch(92% 0.004 286.32);\n --b-context-menu-radius: 8px;\n --b-context-menu-shadow:\n 0 6px 16px 0 oklch(0% 0 0 / 0.08),\n 0 3px 6px -4px oklch(0% 0 0 / 0.12),\n 0 9px 28px 8px oklch(0% 0 0 / 0.05);\n --b-context-menu-padding: 4px;\n --b-context-menu-min-width: 180px;\n --b-context-menu-item-padding-x: 12px;\n --b-context-menu-item-padding-y: 6px;\n --b-context-menu-item-bg-hover: oklch(96% 0.003 286);\n --b-context-menu-item-bg-active: oklch(94% 0.02 240);\n --b-context-menu-item-fg-disabled: oklch(70% 0.005 286);\n --b-context-menu-item-fg-danger: oklch(55% 0.22 25.331);\n --b-context-menu-divider-color: oklch(92% 0.004 286.32);\n\n position: fixed;\n z-index: 1100;\n list-style: none;\n margin: 0;\n padding: var(--b-context-menu-padding);\n min-width: var(--b-context-menu-min-width);\n background: var(--b-context-menu-bg);\n color: var(--b-context-menu-fg);\n border: 1px solid var(--b-context-menu-border-color);\n border-radius: var(--b-context-menu-radius);\n box-shadow: var(--b-context-menu-shadow);\n outline: none;\n font-size: 14px;\n line-height: 1.4;\n}\n\n.b-context-menu__item {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: var(--b-context-menu-item-padding-y) var(--b-context-menu-item-padding-x);\n border-radius: 4px;\n cursor: pointer;\n user-select: none;\n color: inherit;\n transition: background-color 0.12s ease;\n}\n\n.b-context-menu__item:hover {\n background: var(--b-context-menu-item-bg-hover);\n}\n\n.b-context-menu__item--active {\n background: var(--b-context-menu-item-bg-active);\n}\n\n.b-context-menu__item--disabled {\n color: var(--b-context-menu-item-fg-disabled);\n cursor: not-allowed;\n pointer-events: none;\n}\n\n.b-context-menu__item--danger {\n color: var(--b-context-menu-item-fg-danger);\n}\n\n.b-context-menu__item-icon {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 16px;\n height: 16px;\n flex-shrink: 0;\n}\n\n.b-context-menu__item-label {\n flex: 1;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.b-context-menu__divider-row {\n margin: 0;\n padding: 0;\n list-style: none;\n}\n\n.b-context-menu__divider {\n border: 0;\n height: 1px;\n margin: 4px 0;\n background: var(--b-context-menu-divider-color);\n}\n\n/* Animations */\n.b-context-menu-fade-enter-active,\n.b-context-menu-fade-leave-active {\n transition:\n opacity 0.12s ease,\n transform 0.12s ease;\n transform-origin: top left;\n}\n\n.b-context-menu-fade-enter-from,\n.b-context-menu-fade-leave-to {\n opacity: 0;\n transform: scale(0.96);\n}\n\n@media (prefers-reduced-motion: reduce) {\n .b-context-menu-fade-enter-active,\n .b-context-menu-fade-leave-active,\n .b-context-menu__item {\n transition: none;\n }\n}\n\n/* Dark mode — reassign the same vars on both the trigger root and the teleported panel. */\n[data-prefers-color='dark'] .b-context-menu,\n[data-prefers-color='dark'] .b-context-menu__list {\n --b-context-menu-bg: oklch(20% 0.005 286);\n --b-context-menu-fg: oklch(96% 0.002 286);\n --b-context-menu-border-color: oklch(30% 0.005 286);\n --b-context-menu-shadow:\n 0 6px 16px 0 oklch(0% 0 0 / 0.24),\n 0 3px 6px -4px oklch(0% 0 0 / 0.36),\n 0 9px 28px 8px oklch(0% 0 0 / 0.2);\n --b-context-menu-item-bg-hover: oklch(28% 0.005 286);\n --b-context-menu-item-bg-active: oklch(35% 0.04 240);\n --b-context-menu-item-fg-disabled: oklch(55% 0.005 286);\n --b-context-menu-item-fg-danger: oklch(70% 0.18 25);\n --b-context-menu-divider-color: oklch(30% 0.005 286);\n}\n\n@media (prefers-color-scheme: dark) {\n [data-prefers-color='system'] .b-context-menu,\n [data-prefers-color='system'] .b-context-menu__list {\n --b-context-menu-bg: oklch(20% 0.005 286);\n --b-context-menu-fg: oklch(96% 0.002 286);\n --b-context-menu-border-color: oklch(30% 0.005 286);\n --b-context-menu-shadow:\n 0 6px 16px 0 oklch(0% 0 0 / 0.24),\n 0 3px 6px -4px oklch(0% 0 0 / 0.36),\n 0 9px 28px 8px oklch(0% 0 0 / 0.2);\n --b-context-menu-item-bg-hover: oklch(28% 0.005 286);\n --b-context-menu-item-bg-active: oklch(35% 0.04 240);\n --b-context-menu-item-fg-disabled: oklch(55% 0.005 286);\n --b-context-menu-item-fg-danger: oklch(70% 0.18 25);\n --b-context-menu-divider-color: oklch(30% 0.005 286);\n }\n}\n</style>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAuBA,IAAM,IAAO,GAiBP,EAAE,oBAAiB,GAAgB,EACnC,IAAS,QAAe,EAAA,MAAU,kBAAkB,EAAa,QAAQ,EACzE,KAAY,MAAc,GAAG,EAAO,MAAM,QAAQ,KAGlD,IAAS,EAAI,GAAM,EACnB,IAAI,EAAI,EAAE,EACV,IAAI,EAAI,EAAE,EACV,IAAc,EAAI,GAAG,EACrB,IAAU,EAA6B,KAAK,EAC9C,IAAwC,MAGtC,KAAiB,MACrB,CAAC,EAAK,WAAW,CAAC,EAAK,UAEnB,UAAsC,EAAA,MAAM,UAAU,EAAc,EACpE,UAAqC;AACzC,QAAK,IAAI,IAAI,EAAA,MAAM,SAAS,GAAG,KAAK,GAAG,IACrC,KAAI,EAAc,EAAA,MAAM,GAAI,CAAE,QAAO;AAEvC,UAAO;KAGH,KAAc,MAAkB;AACpC,OAAI,EAAA,MAAM,WAAW,EAAG;GACxB,IAAM,IAAM,EAAA,MAAM,QACd,IAAO,EAAY;AACvB,QAAK,IAAI,IAAO,GAAG,IAAO,GAAK,IAE7B,KADA,MAAS,IAAO,KAAS,IAAM,KAAO,GAClC,EAAc,EAAA,MAAM,GAAO,EAAE;AAC/B,MAAY,QAAQ;AACpB;;KAKA,KAAoB,MAAgB;AACpC,OAAM,KAAK,KAAO,EAAA,MAAM,UACxB,EAAc,EAAA,MAAM,GAAM,KAC5B,EAAY,QAAQ;KAIlB,IAAW,QACf,EAAY,SAAS,IAAI,EAAS,EAAY,MAAM,GAAG,KAAA,EACxD,EAGK,KAAqB,MAAsB;AAC3C,KAAA,YACJ,EAAO,EAAM,SAAS,EAAM,SAAS,EAAM;KAGvC,KAAU,GAAY,GAAY,MAAuB;AAc7D,GAbI,OAAO,WAAa,QACtB,IAAqB,SAAS,iBAAwC,OAExE,EAAE,QAAQ,GACV,EAAE,QAAQ,GACV,EAAY,QAAQ,GAAuB,EAC3C,EAAO,QAAQ,IAOf,EAAK,QAJH,MACC,OAAO,aAAe,MACnB,IAAI,WAAW,eAAe;IAAE,SAAS;IAAI,SAAS;IAAI,CAAA,GACzD;IAAE,SAAS;IAAI,SAAS;IAAI,EAClB;KAGb,UAAc;AACb,KAAO,UACZ,EAAO,QAAQ,IACf,EAAK,QAAQ;;AAQf,IAAa;GAEX,OANwB,GAAY,MAAe;AACnD,MAAO,GAAI,EAAG;;GAOd;GACD,CAAC;EAGF,IAAM,UAAsB;AAC1B,OAAI,OAAO,SAAW,IAAa;GACnC,IAAM,IAAK,EAAQ;AACnB,OAAI,CAAC,EAAI;GACT,IAAM,IAAO,EAAG,uBAAuB,EACjC,IAAK,OAAO,cAAc,GAC1B,IAAK,OAAO,eAAe,GAC7B,IAAK,EAAE,OACP,IAAK,EAAE;AAQX,GAPI,IAAK,EAAK,QAAQ,MACpB,IAAK,KAAK,IAAI,GAAG,IAAK,EAAK,MAAM,GAE/B,IAAK,EAAK,SAAS,MACrB,IAAK,KAAK,IAAI,GAAG,IAAK,EAAK,OAAO,GAEpC,EAAE,QAAQ,GACV,EAAE,QAAQ;;AAGZ,IAAM,GAAQ,OAAO,MAAS;AAC5B,OAAI,EAIF,CAHA,MAAM,GAAU,EAChB,GAAe,EACf,EAAQ,OAAO,OAAO,EAClB,OAAO,WAAa,OACtB,SAAS,iBAAiB,aAAa,GAAqB,GAAK;QAE9D;AAKL,QAJI,OAAO,WAAa,OACtB,SAAS,oBAAoB,aAAa,GAAqB,GAAK,EAEtE,EAAY,QAAQ,IAChB,KAAqB,OAAO,EAAkB,SAAU,WAC1D,KAAI;AACF,OAAkB,OAAO;YACnB;AAIV,QAAoB;;IAEtB;EAGF,IAAM,KAAuB,MAAsB;AACjD,OAAI,CAAC,EAAO,MAAO;GACnB,IAAM,IAAS,EAAM;AACjB,QAAU,EAAQ,SAAS,EAAQ,MAAM,SAAS,EAAO,IAC7D,GAAO;KAIH,KAAc,GAAwB,MAAiB;AACvD,WAAK,WAAW,EAAK,UACzB,KAAI;AACF,MAAK,YAAY;aACT;AAER,IADA,EAAK,UAAU,GAAM,EAAM,EAC3B,GAAO;;KAIL,KAAe,GAAwB,GAAa,MAAsB;AAC1E,KAAK,WAAW,EAAK,aACzB,EAAiB,EAAI,EACrB,EAAW,GAAM,EAAM;KAGnB,MAAoB,GAAwB,MAAgB;AAC5D,KAAK,WAAW,EAAK,aACzB,EAAY,QAAQ;KAIhB,MAAa,MAAyB;AAC1C,WAAQ,EAAM,KAAd;IACE,KAAK;AAEH,KADA,EAAM,gBAAgB,EACtB,EAAW,EAAE;AACb;IACF,KAAK;AAEH,KADA,EAAM,gBAAgB,EACtB,EAAW,GAAG;AACd;IACF,KAAK;AAEH,KADA,EAAM,gBAAgB,EACtB,EAAiB,GAAuB,CAAC;AACzC;IACF,KAAK;AAEH,KADA,EAAM,gBAAgB,EACtB,EAAiB,GAAsB,CAAC;AACxC;IACF,KAAK;IACL,KAAK,KAAK;AACR,OAAM,gBAAgB;KACtB,IAAM,IAAM,EAAY;AACxB,SAAI,KAAO,KAAK,IAAM,EAAA,MAAM,QAAQ;MAClC,IAAM,IAAO,EAAA,MAAM;AACnB,MAAI,EAAc,EAAK,IACrB,EAAW,GAAM,EAAM;;AAG3B;;IAEF,KAAK;AAEH,KADA,EAAM,gBAAgB,EACtB,GAAO;AACP;IACF,KAAK;AAEH,QAAO;AACP;;;AAYN,EAPA,QAAsB;AACpB,GAAI,OAAO,WAAa,OACtB,SAAS,oBAAoB,aAAa,GAAqB,GAAK;IAEtE,EAGF,QACQ,EAAA,MAAM,SACX,MAAQ;AACF,KAAO,SACR,EAAY,SAAS,MACvB,EAAY,QAAQ,GAAuB;IAGhD;EAED,IAAM,KAAY,SAAgB;GAChC,KAAK,GAAG,EAAE,MAAM;GAChB,MAAM,GAAG,EAAE,MAAM;GAClB,EAAE;yBAID,EA0DM,OAAA;GA1DD,OAAM;GAAkB,eAAW,EAAU,GAAiB,CAAA,UAAA,CAAA;MACjE,EAAQ,EAAA,QAAA,UAAA,GAAA,GAAA,EAER,EAsDW,GAAA,EAtDD,IAAG,QAAM,EAAA,CACjB,EAoDa,GAAA,EApDD,MAAK,uBAAqB,EAAA;oBAmD/B,CAjDG,EAAA,SAAA,GAAA,EADR,EAkDK,MAAA;;aAhDC;IAAJ,KAAI;IACH,IAAI,EAAA;IACL,MAAK;IACL,oBAAiB;IAChB,cAAY,EAAA;IACZ,yBAAuB,EAAA;IACxB,UAAS;IACT,OAAM;IACL,OAAK,EAAE,GAAA,MAAS;IAChB,WAAS;eAEV,EAoCW,GAAA,MAAA,EApCmB,EAAA,QAAZ,GAAM,wBAAmB,EAAK,KAAA,EAAA,CAEtC,EAAK,WAAA,GAAA,EADb,EAOK,MAPL,GAOK,CAAA,GAAA,AAAA,EAAA,OAAA,CADH,EAAsC,MAAA,EAAlC,OAAM,2BAAyB,EAAA,MAAA,GAAA,CAAA,CAAA,CAAA,KAAA,GAAA,EAErC,EA0BK,MAAA;;IAxBF,IAAI,EAAS,EAAC;IACf,MAAK;IACJ,iBAAa,CAAA,CAAI,EAAK;IACtB,OAAK,EAAA,CAAA,wBAAA;qCAAgH,EAAA,UAAgB;uCAAuD,EAAK;qCAA4D,EAAK;;IAQlQ,UAAK,MAAE,EAAY,GAAM,GAAG,EAAM;IAClC,eAAU,MAAE,GAAiB,GAAM,EAAC;OAErC,EASO,EAAA,QAAA,QAAA;IATkB;IAAO,QAAQ,EAAA,UAAgB;YASjD,CAPG,EAAK,QAAA,GAAA,EADb,EAMO,QANP,GAMO,CADL,EAA+E,GAAA;IAAvE,MAAO,EAAK;IAA+C,MAAK;yCAE1E,EAAgE,QAAhE,GAAgE,EAApB,EAAK,MAAK,EAAA,EAAA,CAAA,CAAA,CAAA,EAAA,IAAA,EAAA,EAAA,EAAA,GAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"design-system71.js","names":[],"sources":["../src/components/BContextMenu/BContextMenu.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport BIcon from '@/components/BIcon/BIcon.vue';\nimport type { BIconBrandName, BIconName } from '@/components/BIcon/BIconEnum.ts';\nimport { useComponentId } from '@/composables/useComponentId.ts';\nimport { computed, nextTick, onBeforeUnmount, ref, watch } from 'vue';\nimport type { BContextMenuItem } from './types.ts';\n\nconst {\n items,\n disabled = false,\n id: idProp,\n ariaLabel = 'Context menu',\n} = defineProps<{\n /** Items to render. Each item is either a regular entry (with `label`) or a divider (`{ divider: true, key }`). */\n items: BContextMenuItem[];\n /** When true, the trigger area ignores `contextmenu` events — the menu cannot be opened. @default false */\n disabled?: boolean;\n /** Optional explicit `id` for the menu element. Falls back to a per-instance auto-generated id. */\n id?: string;\n /** Accessible label announced when the menu opens. @default 'Context menu' */\n ariaLabel?: string;\n}>();\n\nconst emit = defineEmits<{\n /** Emitted when an item is activated (click or Enter/Space). Not emitted for dividers or disabled items. */\n select: [item: BContextMenuItem, event: Event];\n /** Emitted when the menu opens via `contextmenu` (or `open()`). */\n open: [event: MouseEvent];\n /** Emitted when the menu closes. */\n close: [];\n}>();\n\ndefineSlots<{\n /** The trigger area. The component listens for `contextmenu` on the wrapping element. */\n default?(): unknown;\n /** Optional per-item override. Receives `{ item, active }`. */\n item?(props: { item: BContextMenuItem; active: boolean }): unknown;\n}>();\n\n// ── Identity ────────────────────────────────────────────────────────────────\nconst { componentUID } = useComponentId();\nconst baseId = computed(() => idProp ?? `b-context-menu-${componentUID.value}`);\nconst optionId = (i: number) => `${baseId.value}-item-${i}`;\n\n// ── State ───────────────────────────────────────────────────────────────────\nconst isOpen = ref(false);\nconst x = ref(0);\nconst y = ref(0);\nconst activeIndex = ref(-1);\nconst menuRef = ref<HTMLUListElement | null>(null);\nlet previouslyFocused: HTMLElement | null = null;\n\n// ── Activatable items (skip dividers + disabled) ────────────────────────────\nconst isActivatable = (item: BContextMenuItem): boolean =>\n !item.divider && !item.disabled;\n\nconst firstActivatableIndex = (): number => items.findIndex(isActivatable);\nconst lastActivatableIndex = (): number => {\n for (let i = items.length - 1; i >= 0; i--) {\n if (isActivatable(items[i]!)) return i;\n }\n return -1;\n};\n\nconst moveActive = (delta: number) => {\n if (items.length === 0) return;\n const len = items.length;\n let next = activeIndex.value;\n for (let step = 0; step < len; step++) {\n next = ((next + delta) % len + len) % len;\n if (isActivatable(items[next]!)) {\n activeIndex.value = next;\n return;\n }\n }\n};\n\nconst setActiveByIndex = (idx: number) => {\n if (idx < 0 || idx >= items.length) return;\n if (isActivatable(items[idx]!)) {\n activeIndex.value = idx;\n }\n};\n\nconst activeId = computed(() =>\n activeIndex.value >= 0 ? optionId(activeIndex.value) : undefined,\n);\n\n// ── Open / close ────────────────────────────────────────────────────────────\nconst handleContextMenu = (event: MouseEvent) => {\n if (disabled) return;\n openAt(event.clientX, event.clientY, event);\n};\n\nconst openAt = (px: number, py: number, event?: MouseEvent) => {\n if (typeof document !== 'undefined') {\n previouslyFocused = (document.activeElement as HTMLElement | null) ?? null;\n }\n x.value = px;\n y.value = py;\n activeIndex.value = firstActivatableIndex();\n isOpen.value = true;\n // Synthesize a MouseEvent-like object if called programmatically.\n const evt =\n event ??\n (typeof MouseEvent !== 'undefined'\n ? new MouseEvent('contextmenu', { clientX: px, clientY: py })\n : ({ clientX: px, clientY: py } as MouseEvent));\n emit('open', evt);\n};\n\nconst close = () => {\n if (!isOpen.value) return;\n isOpen.value = false;\n emit('close');\n};\n\n// Public API.\nconst openProgrammatic = (px: number, py: number) => {\n openAt(px, py);\n};\n\ndefineExpose({\n /** Open the menu programmatically at viewport coordinates. */\n open: openProgrammatic,\n /** Close the menu programmatically. */\n close,\n});\n\n// ── Position clamping & focus ───────────────────────────────────────────────\nconst clampPosition = () => {\n if (typeof window === 'undefined') return;\n const el = menuRef.value;\n if (!el) return;\n const rect = el.getBoundingClientRect();\n const vw = window.innerWidth || 0;\n const vh = window.innerHeight || 0;\n let nx = x.value;\n let ny = y.value;\n if (nx + rect.width > vw) {\n nx = Math.max(0, nx - rect.width);\n }\n if (ny + rect.height > vh) {\n ny = Math.max(0, ny - rect.height);\n }\n x.value = nx;\n y.value = ny;\n};\n\nwatch(isOpen, async (open) => {\n if (open) {\n await nextTick();\n clampPosition();\n menuRef.value?.focus();\n if (typeof document !== 'undefined') {\n document.addEventListener('mousedown', onDocumentMouseDown, true);\n }\n } else {\n if (typeof document !== 'undefined') {\n document.removeEventListener('mousedown', onDocumentMouseDown, true);\n }\n activeIndex.value = -1;\n if (previouslyFocused && typeof previouslyFocused.focus === 'function') {\n try {\n previouslyFocused.focus();\n } catch {\n // ignore — element may have been removed\n }\n }\n previouslyFocused = null;\n }\n});\n\n// ── Click-outside ───────────────────────────────────────────────────────────\nconst onDocumentMouseDown = (event: MouseEvent) => {\n if (!isOpen.value) return;\n const target = event.target as Node | null;\n if (target && menuRef.value && menuRef.value.contains(target)) return;\n close();\n};\n\n// ── Selection ───────────────────────────────────────────────────────────────\nconst selectItem = (item: BContextMenuItem, event: Event) => {\n if (item.divider || item.disabled) return;\n try {\n item.onSelect?.();\n } finally {\n emit('select', item, event);\n close();\n }\n};\n\nconst onItemClick = (item: BContextMenuItem, idx: number, event: MouseEvent) => {\n if (item.divider || item.disabled) return;\n setActiveByIndex(idx);\n selectItem(item, event);\n};\n\nconst onItemMouseEnter = (item: BContextMenuItem, idx: number) => {\n if (item.divider || item.disabled) return;\n activeIndex.value = idx;\n};\n\n// ── Keyboard ────────────────────────────────────────────────────────────────\nconst onKeyDown = (event: KeyboardEvent) => {\n switch (event.key) {\n case 'ArrowDown':\n event.preventDefault();\n moveActive(1);\n break;\n case 'ArrowUp':\n event.preventDefault();\n moveActive(-1);\n break;\n case 'Home':\n event.preventDefault();\n setActiveByIndex(firstActivatableIndex());\n break;\n case 'End':\n event.preventDefault();\n setActiveByIndex(lastActivatableIndex());\n break;\n case 'Enter':\n case ' ': {\n event.preventDefault();\n const idx = activeIndex.value;\n if (idx >= 0 && idx < items.length) {\n const item = items[idx]!;\n if (isActivatable(item)) {\n selectItem(item, event);\n }\n }\n break;\n }\n case 'Escape':\n event.preventDefault();\n close();\n break;\n case 'Tab':\n // Close — let Tab focus traversal continue naturally.\n close();\n break;\n }\n};\n\n// ── Cleanup ─────────────────────────────────────────────────────────────────\nonBeforeUnmount(() => {\n if (typeof document !== 'undefined') {\n document.removeEventListener('mousedown', onDocumentMouseDown, true);\n }\n});\n\n// Reset the active index if items shrink while open.\nwatch(\n () => items.length,\n (len) => {\n if (!isOpen.value) return;\n if (activeIndex.value >= len) {\n activeIndex.value = firstActivatableIndex();\n }\n },\n);\n\nconst menuStyle = computed(() => ({\n top: `${y.value}px`,\n left: `${x.value}px`,\n}));\n</script>\n\n<template>\n <div class=\"b-context-menu\" @contextmenu.prevent=\"handleContextMenu\">\n <slot />\n\n <Teleport to=\"body\">\n <Transition name=\"b-context-menu-fade\">\n <ul\n v-if=\"isOpen\"\n ref=\"menuRef\"\n :id=\"baseId\"\n role=\"menu\"\n aria-orientation=\"vertical\"\n :aria-label=\"ariaLabel\"\n :aria-activedescendant=\"activeId\"\n tabindex=\"-1\"\n class=\"b-context-menu__list\"\n :style=\"menuStyle\"\n @keydown=\"onKeyDown\"\n >\n <template v-for=\"(item, i) in items\" :key=\"item.key\">\n <li\n v-if=\"item.divider\"\n role=\"separator\"\n aria-hidden=\"true\"\n class=\"b-context-menu__divider-row\"\n >\n <hr class=\"b-context-menu__divider\" />\n </li>\n <li\n v-else\n :id=\"optionId(i)\"\n role=\"menuitem\"\n :aria-disabled=\"!!item.disabled\"\n :class=\"[\n 'b-context-menu__item',\n {\n 'b-context-menu__item--active': activeIndex === i,\n 'b-context-menu__item--disabled': item.disabled,\n 'b-context-menu__item--danger': item.danger,\n },\n ]\"\n @click=\"onItemClick(item, i, $event)\"\n @mouseenter=\"onItemMouseEnter(item, i)\"\n >\n <slot name=\"item\" :item=\"item\" :active=\"activeIndex === i\">\n <span\n v-if=\"item.icon\"\n class=\"b-context-menu__item-icon\"\n aria-hidden=\"true\"\n >\n <BIcon :icon=\"(item.icon as `${BIconName}` | `${BIconBrandName}`)\" size=\"sm\" />\n </span>\n <span class=\"b-context-menu__item-label\">{{ item.label }}</span>\n </slot>\n </li>\n </template>\n </ul>\n </Transition>\n </Teleport>\n </div>\n</template>\n\n<style>\n.b-context-menu {\n /* Trigger wrapper — also defines the tokens so consumers can override on the wrapper. */\n --b-context-menu-bg: oklch(100% 0 0);\n --b-context-menu-fg: oklch(20% 0.005 286);\n --b-context-menu-border-color: oklch(92% 0.004 286.32);\n --b-context-menu-radius: 8px;\n --b-context-menu-shadow:\n 0 6px 16px 0 oklch(0% 0 0 / 0.08),\n 0 3px 6px -4px oklch(0% 0 0 / 0.12),\n 0 9px 28px 8px oklch(0% 0 0 / 0.05);\n --b-context-menu-padding: 4px;\n --b-context-menu-min-width: 180px;\n --b-context-menu-item-padding-x: 12px;\n --b-context-menu-item-padding-y: 6px;\n --b-context-menu-item-bg-hover: oklch(96% 0.003 286);\n --b-context-menu-item-bg-active: oklch(94% 0.02 240);\n --b-context-menu-item-fg-disabled: oklch(70% 0.005 286);\n --b-context-menu-item-fg-danger: oklch(55% 0.22 25.331);\n --b-context-menu-divider-color: oklch(92% 0.004 286.32);\n}\n\n/* The list is teleported to <body> — re-declare tokens on its root so they resolve. */\n.b-context-menu__list {\n --b-context-menu-bg: oklch(100% 0 0);\n --b-context-menu-fg: oklch(20% 0.005 286);\n --b-context-menu-border-color: oklch(92% 0.004 286.32);\n --b-context-menu-radius: 8px;\n --b-context-menu-shadow:\n 0 6px 16px 0 oklch(0% 0 0 / 0.08),\n 0 3px 6px -4px oklch(0% 0 0 / 0.12),\n 0 9px 28px 8px oklch(0% 0 0 / 0.05);\n --b-context-menu-padding: 4px;\n --b-context-menu-min-width: 180px;\n --b-context-menu-item-padding-x: 12px;\n --b-context-menu-item-padding-y: 6px;\n --b-context-menu-item-bg-hover: oklch(96% 0.003 286);\n --b-context-menu-item-bg-active: oklch(94% 0.02 240);\n --b-context-menu-item-fg-disabled: oklch(70% 0.005 286);\n --b-context-menu-item-fg-danger: oklch(55% 0.22 25.331);\n --b-context-menu-divider-color: oklch(92% 0.004 286.32);\n\n position: fixed;\n z-index: 1100;\n list-style: none;\n margin: 0;\n padding: var(--b-context-menu-padding);\n min-width: var(--b-context-menu-min-width);\n background: var(--b-context-menu-bg);\n color: var(--b-context-menu-fg);\n border: 1px solid var(--b-context-menu-border-color);\n border-radius: var(--b-context-menu-radius);\n box-shadow: var(--b-context-menu-shadow);\n outline: none;\n font-size: 14px;\n line-height: 1.4;\n}\n\n.b-context-menu__item {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: var(--b-context-menu-item-padding-y) var(--b-context-menu-item-padding-x);\n border-radius: 4px;\n cursor: pointer;\n user-select: none;\n color: inherit;\n transition: background-color 0.12s ease;\n}\n\n.b-context-menu__item:hover {\n background: var(--b-context-menu-item-bg-hover);\n}\n\n.b-context-menu__item--active {\n background: var(--b-context-menu-item-bg-active);\n}\n\n.b-context-menu__item--disabled {\n color: var(--b-context-menu-item-fg-disabled);\n cursor: not-allowed;\n pointer-events: none;\n}\n\n.b-context-menu__item--danger {\n color: var(--b-context-menu-item-fg-danger);\n}\n\n.b-context-menu__item-icon {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 16px;\n height: 16px;\n flex-shrink: 0;\n}\n\n.b-context-menu__item-label {\n flex: 1;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.b-context-menu__divider-row {\n margin: 0;\n padding: 0;\n list-style: none;\n}\n\n.b-context-menu__divider {\n border: 0;\n height: 1px;\n margin: 4px 0;\n background: var(--b-context-menu-divider-color);\n}\n\n/* Animations */\n.b-context-menu-fade-enter-active,\n.b-context-menu-fade-leave-active {\n transition:\n opacity 0.12s ease,\n transform 0.12s ease;\n transform-origin: top left;\n}\n\n.b-context-menu-fade-enter-from,\n.b-context-menu-fade-leave-to {\n opacity: 0;\n transform: scale(0.96);\n}\n\n@media (prefers-reduced-motion: reduce) {\n .b-context-menu-fade-enter-active,\n .b-context-menu-fade-leave-active,\n .b-context-menu__item {\n transition: none;\n }\n}\n\n/* Dark mode — reassign the same vars on both the trigger root and the teleported panel. */\n[data-prefers-color='dark'] .b-context-menu,\n[data-prefers-color='dark'] .b-context-menu__list {\n --b-context-menu-bg: oklch(20% 0.005 286);\n --b-context-menu-fg: oklch(96% 0.002 286);\n --b-context-menu-border-color: oklch(30% 0.005 286);\n --b-context-menu-shadow:\n 0 6px 16px 0 oklch(0% 0 0 / 0.24),\n 0 3px 6px -4px oklch(0% 0 0 / 0.36),\n 0 9px 28px 8px oklch(0% 0 0 / 0.2);\n --b-context-menu-item-bg-hover: oklch(28% 0.005 286);\n --b-context-menu-item-bg-active: oklch(35% 0.04 240);\n --b-context-menu-item-fg-disabled: oklch(55% 0.005 286);\n --b-context-menu-item-fg-danger: oklch(70% 0.18 25);\n --b-context-menu-divider-color: oklch(30% 0.005 286);\n}\n\n@media (prefers-color-scheme: dark) {\n [data-prefers-color='system'] .b-context-menu,\n [data-prefers-color='system'] .b-context-menu__list {\n --b-context-menu-bg: oklch(20% 0.005 286);\n --b-context-menu-fg: oklch(96% 0.002 286);\n --b-context-menu-border-color: oklch(30% 0.005 286);\n --b-context-menu-shadow:\n 0 6px 16px 0 oklch(0% 0 0 / 0.24),\n 0 3px 6px -4px oklch(0% 0 0 / 0.36),\n 0 9px 28px 8px oklch(0% 0 0 / 0.2);\n --b-context-menu-item-bg-hover: oklch(28% 0.005 286);\n --b-context-menu-item-bg-active: oklch(35% 0.04 240);\n --b-context-menu-item-fg-disabled: oklch(55% 0.005 286);\n --b-context-menu-item-fg-danger: oklch(70% 0.18 25);\n --b-context-menu-divider-color: oklch(30% 0.005 286);\n }\n}\n</style>\n"],"mappings":""}
|
package/dist/design-system72.js
CHANGED
|
@@ -1,8 +1,16 @@
|
|
|
1
|
-
|
|
2
|
-
/*
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
//#region src/components/BDatePicker/types.ts
|
|
2
|
+
var e = /* @__PURE__ */ function(e) {
|
|
3
|
+
return e.Date = "date", e.Week = "week", e.Month = "month", e.Quarter = "quarter", e.Year = "year", e;
|
|
4
|
+
}({}), t = /* @__PURE__ */ function(e) {
|
|
5
|
+
return e.Small = "sm", e.Medium = "md", e.Large = "lg", e;
|
|
6
|
+
}({}), n = /* @__PURE__ */ function(e) {
|
|
7
|
+
return e.Outlined = "outlined", e.Filled = "filled", e.Borderless = "borderless", e.Underlined = "underlined", e;
|
|
8
|
+
}({}), r = /* @__PURE__ */ function(e) {
|
|
9
|
+
return e.Error = "error", e.Warning = "warning", e;
|
|
10
|
+
}({}), i = /* @__PURE__ */ function(e) {
|
|
11
|
+
return e.BottomLeft = "bottom-left", e.BottomRight = "bottom-right", e.TopLeft = "top-left", e.TopRight = "top-right", e;
|
|
12
|
+
}({});
|
|
5
13
|
//#endregion
|
|
6
|
-
export { t as
|
|
14
|
+
export { i as BDatePickerPlacement, t as BDatePickerSize, r as BDatePickerStatus, e as BDatePickerType, n as BDatePickerVariant };
|
|
7
15
|
|
|
8
16
|
//# sourceMappingURL=design-system72.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"design-system72.js","names":[],"sources":["../src/components/BDatePicker/BDatePicker.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { useComponentId } from '@/composables/useComponentId.ts';\nimport { computed, ref, watch } from 'vue';\n\nimport {\n BDatePickerPlacement,\n BDatePickerSize,\n BDatePickerStatus,\n BDatePickerType,\n BDatePickerVariant,\n type BDatePickerDisabledDateInfo,\n type BDatePickerPreset,\n} from './types';\n\nconst {\n picker = BDatePickerType.Date,\n size = BDatePickerSize.Medium,\n variant = BDatePickerVariant.Outlined,\n placeholder,\n disabled = false,\n inputReadOnly = false,\n allowClear = true,\n showNow = true,\n showWeek = false,\n format,\n locale,\n placement: _placement = BDatePickerPlacement.BottomLeft,\n status,\n presets,\n disabledDate,\n minDate,\n maxDate,\n defaultOpen = false,\n defaultValue,\n defaultPickerValue,\n open,\n} = defineProps<{\n /** Picker type: date, week, month, quarter, year */\n picker?: `${BDatePickerType}`;\n /** Size of the input */\n size?: `${BDatePickerSize}`;\n /** Visual variant */\n variant?: `${BDatePickerVariant}`;\n /** Placeholder text */\n placeholder?: string;\n /** Disable the picker */\n disabled?: boolean;\n /** Make input read-only */\n inputReadOnly?: boolean;\n /** Show clear button */\n allowClear?: boolean;\n /** Show \"Today\" / \"Now\" button */\n showNow?: boolean;\n /** Show week number column (date picker) */\n showWeek?: boolean;\n /** Date format string (e.g. 'YYYY-MM-DD', 'DD/MM/YYYY', 'MM-DD-YYYY') */\n format?: string;\n /** BCP 47 locale tag for formatting and calendar labels (e.g. 'en-US', 'vi-VN', 'de-DE') */\n locale?: string;\n /** Popup placement */\n placement?: `${BDatePickerPlacement}`;\n /** Validation status */\n status?: `${BDatePickerStatus}`;\n /** Preset quick-select values */\n presets?: BDatePickerPreset[];\n /** Function to determine if a date is disabled */\n disabledDate?: (current: Date, info: BDatePickerDisabledDateInfo) => boolean;\n /** Minimum selectable date */\n minDate?: Date;\n /** Maximum selectable date */\n maxDate?: Date;\n /** Default open state */\n defaultOpen?: boolean;\n /** Default value (uncontrolled) */\n defaultValue?: Date;\n /** Default panel date */\n defaultPickerValue?: Date;\n /** Controlled open state */\n open?: boolean;\n}>();\n\nconst model = defineModel<Date | null>({ default: undefined });\n\nconst emit = defineEmits<{\n change: [date: Date | null, dateString: string];\n openChange: [open: boolean];\n panelChange: [date: Date, mode: string];\n ok: [];\n}>();\n\ndefineExpose({\n focus: () => inputEl.value?.focus(),\n blur: () => inputEl.value?.blur(),\n});\n\nconst { componentUID } = useComponentId();\nconst anchorName = computed(() => `--b-date-picker-${componentUID.value}`);\n\n// ─────────────────────────────────────────────\n// State\n// ─────────────────────────────────────────────\nconst inputEl = ref<HTMLInputElement | null>(null);\nconst panelEl = ref<HTMLElement | null>(null);\nconst isOpen = ref(defaultOpen);\nconst internalValue = ref<Date | null>(defaultValue ?? null);\nconst panelDate = ref<Date>(defaultPickerValue ?? defaultValue ?? new Date());\nconst panelMode = ref<string>(picker);\nconst hoveredDate = ref<Date | null>(null);\n\nconst selectedDate = computed({\n get: () => model.value ?? internalValue.value,\n set: (val) => {\n internalValue.value = val;\n model.value = val;\n },\n});\n\nconst isPanelOpen = ref(open !== undefined ? !!open : defaultOpen);\n\n// ─────────────────────────────────────────────\n// Formatting & Locale\n// ─────────────────────────────────────────────\nconst resolvedLocale = computed(() => {\n const tag = locale || navigator?.language || 'en-US';\n try {\n Intl.DateTimeFormat(tag);\n return tag;\n } catch {\n return 'en-US';\n }\n});\n\nconst defaultFormats: Record<string, string> = {\n date: 'YYYY-MM-DD',\n week: 'YYYY-[W]wo',\n month: 'YYYY-MM',\n quarter: 'YYYY-[Q]Q',\n year: 'YYYY',\n};\n\nconst activeFormat = computed(() => format ?? defaultFormats[picker] ?? 'YYYY-MM-DD');\n\nfunction pad(n: number, len = 2): string {\n return String(n).padStart(len, '0');\n}\n\nfunction getWeekNumber(d: Date): number {\n const copy = new Date(Date.UTC(d.getFullYear(), d.getMonth(), d.getDate()));\n copy.setUTCDate(copy.getUTCDate() + 4 - (copy.getUTCDay() || 7));\n const yearStart = new Date(Date.UTC(copy.getUTCFullYear(), 0, 1));\n return Math.ceil(((copy.getTime() - yearStart.getTime()) / 86400000 + 1) / 7);\n}\n\nfunction formatDate(date: Date | null): string {\n if (!date) return '';\n const y = date.getFullYear();\n const m = date.getMonth() + 1;\n const d = date.getDate();\n\n let fmt = activeFormat.value;\n\n // Escape sequences: text inside [] is literal\n const DELIM = '';\n const literals: string[] = [];\n fmt = fmt.replace(/\\[([^\\]]*)\\]/g, (_, text) => {\n literals.push(text);\n return `${DELIM}${literals.length - 1}${DELIM}`;\n });\n\n // Token replacement (longest tokens first to avoid partial matches)\n fmt = fmt.replace('YYYY', String(y));\n fmt = fmt.replace('YY', String(y).slice(-2));\n fmt = fmt.replace('MM', pad(m));\n fmt = fmt.replace('M', String(m));\n fmt = fmt.replace('DD', pad(d));\n fmt = fmt.replace('D', String(d));\n fmt = fmt.replace('wo', String(getWeekNumber(date)));\n fmt = fmt.replace('Q', String(Math.ceil(m / 3)));\n\n // Restore literals\n fmt = fmt.replace(new RegExp(`${DELIM}(\\\\d+)${DELIM}`, 'g'), (_, idx) => literals[Number(idx)]);\n\n return fmt;\n}\n\nfunction parseInput(value: string): Date | null {\n if (!value) return null;\n\n // Try parsing based on current format pattern\n const fmt = activeFormat.value;\n const parsed = parseByFormat(value, fmt);\n if (parsed) return parsed;\n\n // Fallback: ISO format\n const iso = value.match(/^(\\d{4})-(\\d{1,2})-(\\d{1,2})$/);\n if (iso) {\n const date = new Date(Number(iso[1]), Number(iso[2]) - 1, Number(iso[3]));\n if (!isNaN(date.getTime())) return date;\n }\n\n // Fallback: native Date parsing\n const date = new Date(value);\n return isNaN(date.getTime()) ? null : date;\n}\n\nfunction parseByFormat(value: string, fmt: string): Date | null {\n let regex = fmt.replace(/\\[([^\\]]*)\\]/g, (_, text) => escapeRegex(text));\n const groups: { token: string; pos: number }[] = [];\n\n const tokenMap: [string, string][] = [\n ['YYYY', '(\\\\d{4})'],\n ['YY', '(\\\\d{2})'],\n ['MM', '(\\\\d{2})'],\n ['M', '(\\\\d{1,2})'],\n ['DD', '(\\\\d{2})'],\n ['D', '(\\\\d{1,2})'],\n ];\n\n for (const [token, pattern] of tokenMap) {\n const idx = regex.indexOf(token);\n if (idx !== -1) {\n regex = regex.replace(token, pattern);\n groups.push({ token, pos: idx });\n }\n }\n\n groups.sort((a, b) => a.pos - b.pos);\n\n regex = regex.replace('wo', '\\\\d{1,2}');\n regex = regex.replace('Q', '\\\\d');\n\n try {\n const match = value.match(new RegExp(`^${regex}$`));\n if (!match) return null;\n\n let year = new Date().getFullYear();\n let month = 1;\n let day = 1;\n\n groups.forEach(({ token }, i) => {\n const val = Number(match[i + 1]);\n switch (token) {\n case 'YYYY':\n year = val;\n break;\n case 'YY':\n year = 2000 + val;\n break;\n case 'MM':\n case 'M':\n month = val;\n break;\n case 'DD':\n case 'D':\n day = val;\n break;\n }\n });\n\n const date = new Date(year, month - 1, day);\n if (isNaN(date.getTime())) return null;\n if (date.getFullYear() !== year || date.getMonth() !== month - 1 || date.getDate() !== day)\n return null;\n return date;\n } catch {\n return null;\n }\n}\n\nfunction escapeRegex(str: string): string {\n return str.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n}\n\nconst displayValue = computed(() => formatDate(selectedDate.value));\n\n// ─────────────────────────────────────────────\n// Locale-aware calendar labels\n// ─────────────────────────────────────────────\nconst weekdayLabels = computed(() => {\n const loc = resolvedLocale.value;\n const labels: string[] = [];\n for (let i = 0; i < 7; i++) {\n // Jan 7, 2024 is a Sunday — offset by i to get Sun..Sat\n const day = new Date(2024, 0, 7 + i);\n labels.push(day.toLocaleDateString(loc, { weekday: 'short' }).slice(0, 2));\n }\n return labels;\n});\n\nconst monthLabels = computed(() => {\n const loc = resolvedLocale.value;\n return Array.from({ length: 12 }, (_, i) =>\n new Date(2024, i, 1).toLocaleDateString(loc, { month: 'short' }),\n );\n});\n\nconst todayLabel = computed(() => {\n const loc = resolvedLocale.value;\n // Use Intl to get localized \"Today\" - fallback to English\n try {\n const rtf = new Intl.RelativeTimeFormat(loc, { numeric: 'auto' });\n const parts = rtf.formatToParts(0, 'day');\n const value = parts.find((p) => p.type === 'literal')?.value;\n if (value && value.trim()) return value.trim().charAt(0).toUpperCase() + value.trim().slice(1);\n } catch {\n /* fallback */\n }\n return 'Today';\n});\n\n// ─────────────────────────────────────────────\n// Calendar data generation\n// ─────────────────────────────────────────────\nconst calendarDates = computed(() => {\n const year = panelDate.value.getFullYear();\n const month = panelDate.value.getMonth();\n const firstDay = new Date(year, month, 1);\n const startDay = firstDay.getDay();\n const dates: { date: Date; current: boolean }[] = [];\n\n for (let i = startDay - 1; i >= 0; i--) {\n dates.push({ date: new Date(year, month, -i), current: false });\n }\n const daysInMonth = new Date(year, month + 1, 0).getDate();\n for (let i = 1; i <= daysInMonth; i++) {\n dates.push({ date: new Date(year, month, i), current: true });\n }\n const remaining = 42 - dates.length;\n for (let i = 1; i <= remaining; i++) {\n dates.push({ date: new Date(year, month + 1, i), current: false });\n }\n return dates;\n});\n\nconst calendarMonths = computed(() => {\n return monthLabels.value.map((label, idx) => ({\n label,\n month: idx,\n year: panelDate.value.getFullYear(),\n }));\n});\n\nconst calendarYears = computed(() => {\n const year = panelDate.value.getFullYear();\n const decadeStart = Math.floor(year / 10) * 10;\n const years: { year: number; current: boolean }[] = [];\n for (let i = decadeStart - 1; i <= decadeStart + 10; i++) {\n years.push({ year: i, current: i >= decadeStart && i < decadeStart + 10 });\n }\n return years;\n});\n\nconst calendarQuarters = computed(() => {\n const year = panelDate.value.getFullYear();\n return [1, 2, 3, 4].map((q) => ({ quarter: q, year, label: `Q${q}` }));\n});\n\nconst panelHeading = computed(() => {\n const y = panelDate.value.getFullYear();\n const m = panelDate.value.getMonth();\n if (panelMode.value === 'date' || panelMode.value === 'week') {\n return `${monthLabels.value[m]} ${y}`;\n }\n if (panelMode.value === 'month' || panelMode.value === 'quarter') {\n return `${y}`;\n }\n if (panelMode.value === 'year') {\n const decadeStart = Math.floor(y / 10) * 10;\n return `${decadeStart} - ${decadeStart + 9}`;\n }\n return `${y}`;\n});\n\n// ─────────────────────────────────────────────\n// Date checks\n// ─────────────────────────────────────────────\nfunction isSameDay(a: Date, b: Date): boolean {\n return (\n a.getFullYear() === b.getFullYear() &&\n a.getMonth() === b.getMonth() &&\n a.getDate() === b.getDate()\n );\n}\n\nfunction isToday(d: Date): boolean {\n return isSameDay(d, new Date());\n}\n\nfunction isSelected(d: Date): boolean {\n return selectedDate.value ? isSameDay(d, selectedDate.value) : false;\n}\n\nfunction isDateDisabled(d: Date): boolean {\n if (minDate && d < new Date(minDate.getFullYear(), minDate.getMonth(), minDate.getDate()))\n return true;\n if (maxDate && d > new Date(maxDate.getFullYear(), maxDate.getMonth(), maxDate.getDate()))\n return true;\n if (disabledDate) return disabledDate(d, { type: picker as `${BDatePickerType}` });\n return false;\n}\n\n// ─────────────────────────────────────────────\n// Panel open/close\n// ─────────────────────────────────────────────\nfunction openPanel() {\n if (disabled) return;\n isOpen.value = true;\n isPanelOpen.value = true;\n emit('openChange', true);\n panelEl.value?.showPopover?.();\n inputEl.value?.focus();\n}\n\nfunction closePanel() {\n isOpen.value = false;\n isPanelOpen.value = false;\n emit('openChange', false);\n panelEl.value?.hidePopover?.();\n inputEl.value?.focus();\n}\n\nfunction togglePanel() {\n if (isPanelOpen.value) {\n closePanel();\n } else {\n openPanel();\n }\n}\n\nfunction handlePopoverToggle(e: Event) {\n const toggleEvent = e as ToggleEvent;\n const nowOpen = toggleEvent.newState === 'open';\n isOpen.value = nowOpen;\n isPanelOpen.value = nowOpen;\n if (!nowOpen) {\n emit('openChange', false);\n }\n}\n\n// ─────────────────────────────────────────────\n// Selection handlers\n// ─────────────────────────────────────────────\nfunction selectDate(d: Date) {\n if (isDateDisabled(d)) return;\n selectedDate.value = d;\n panelDate.value = new Date(d);\n emit('change', d, formatDate(d));\n closePanel();\n}\n\nfunction selectMonth(month: number) {\n if (picker === BDatePickerType.Month) {\n const d = new Date(panelDate.value.getFullYear(), month, 1);\n selectedDate.value = d;\n emit('change', d, formatDate(d));\n closePanel();\n } else {\n panelDate.value = new Date(panelDate.value.getFullYear(), month, 1);\n panelMode.value = 'date';\n emit('panelChange', panelDate.value, 'date');\n }\n}\n\nfunction selectYear(year: number) {\n if (picker === BDatePickerType.Year) {\n const d = new Date(year, 0, 1);\n selectedDate.value = d;\n emit('change', d, formatDate(d));\n closePanel();\n } else {\n panelDate.value = new Date(year, panelDate.value.getMonth(), 1);\n panelMode.value = picker === BDatePickerType.Month ? 'month' : 'date';\n emit('panelChange', panelDate.value, panelMode.value);\n }\n}\n\nfunction selectQuarter(quarter: number) {\n const d = new Date(panelDate.value.getFullYear(), (quarter - 1) * 3, 1);\n selectedDate.value = d;\n emit('change', d, formatDate(d));\n closePanel();\n}\n\nfunction selectToday() {\n const today = new Date();\n today.setHours(0, 0, 0, 0);\n selectDate(today);\n}\n\nfunction selectPreset(preset: BDatePickerPreset) {\n const val = typeof preset.value === 'function' ? preset.value() : preset.value;\n selectDate(val);\n}\n\nfunction clearValue(e: Event) {\n e.stopPropagation();\n selectedDate.value = null;\n emit('change', null, '');\n}\n\n// ─────────────────────────────────────────────\n// Navigation\n// ─────────────────────────────────────────────\nfunction prevMonth() {\n panelDate.value = new Date(panelDate.value.getFullYear(), panelDate.value.getMonth() - 1, 1);\n}\n\nfunction nextMonth() {\n panelDate.value = new Date(panelDate.value.getFullYear(), panelDate.value.getMonth() + 1, 1);\n}\n\nfunction prevYear() {\n panelDate.value = new Date(panelDate.value.getFullYear() - 1, panelDate.value.getMonth(), 1);\n}\n\nfunction nextYear() {\n panelDate.value = new Date(panelDate.value.getFullYear() + 1, panelDate.value.getMonth(), 1);\n}\n\nfunction prevDecade() {\n panelDate.value = new Date(panelDate.value.getFullYear() - 10, panelDate.value.getMonth(), 1);\n}\n\nfunction nextDecade() {\n panelDate.value = new Date(panelDate.value.getFullYear() + 10, panelDate.value.getMonth(), 1);\n}\n\nfunction switchPanelMode(mode: string) {\n panelMode.value = mode;\n emit('panelChange', panelDate.value, mode);\n}\n\n// ─────────────────────────────────────────────\n// Input handling\n// ─────────────────────────────────────────────\nconst inputText = ref('');\n\nfunction handleInputChange(e: Event) {\n const value = (e.target as HTMLInputElement).value;\n inputText.value = value;\n}\n\nfunction handleInputBlur() {\n if (inputText.value) {\n const parsed = parseInput(inputText.value);\n if (parsed && !isDateDisabled(parsed)) {\n selectedDate.value = parsed;\n panelDate.value = new Date(parsed);\n emit('change', parsed, formatDate(parsed));\n }\n }\n inputText.value = '';\n}\n\nfunction handleInputKeydown(e: KeyboardEvent) {\n if (e.key === 'Enter') {\n if (!isPanelOpen.value) {\n openPanel();\n } else {\n handleInputBlur();\n closePanel();\n }\n } else if (e.key === 'Escape') {\n closePanel();\n } else if (e.key === 'ArrowDown' && !isPanelOpen.value) {\n openPanel();\n }\n}\n\n// ─────────────────────────────────────────────\n// Keyboard navigation in panel\n// ─────────────────────────────────────────────\nfunction handlePanelKeydown(e: KeyboardEvent) {\n if (e.key === 'Escape') {\n closePanel();\n return;\n }\n\n if (panelMode.value === 'date' || panelMode.value === 'week') {\n handleDateKeydown(e);\n } else if (panelMode.value === 'month') {\n handleMonthKeydown(e);\n } else if (panelMode.value === 'year') {\n handleYearKeydown(e);\n }\n}\n\nfunction handleDateKeydown(e: KeyboardEvent) {\n const pd = new Date(panelDate.value);\n let moved = false;\n\n switch (e.key) {\n case 'ArrowLeft':\n pd.setDate(pd.getDate() - 1);\n moved = true;\n break;\n case 'ArrowRight':\n pd.setDate(pd.getDate() + 1);\n moved = true;\n break;\n case 'ArrowUp':\n pd.setDate(pd.getDate() - 7);\n moved = true;\n break;\n case 'ArrowDown':\n pd.setDate(pd.getDate() + 7);\n moved = true;\n break;\n case 'Enter':\n case ' ':\n e.preventDefault();\n selectDate(panelDate.value);\n return;\n case 'PageUp':\n if (e.shiftKey) {\n prevYear();\n } else {\n prevMonth();\n }\n e.preventDefault();\n return;\n case 'PageDown':\n if (e.shiftKey) {\n nextYear();\n } else {\n nextMonth();\n }\n e.preventDefault();\n return;\n }\n\n if (moved) {\n e.preventDefault();\n panelDate.value = pd;\n }\n}\n\nfunction handleMonthKeydown(e: KeyboardEvent) {\n const currentMonth = panelDate.value.getMonth();\n let newMonth = currentMonth;\n\n switch (e.key) {\n case 'ArrowLeft':\n newMonth = currentMonth - 1;\n break;\n case 'ArrowRight':\n newMonth = currentMonth + 1;\n break;\n case 'ArrowUp':\n newMonth = currentMonth - 3;\n break;\n case 'ArrowDown':\n newMonth = currentMonth + 3;\n break;\n case 'Enter':\n case ' ':\n e.preventDefault();\n selectMonth(currentMonth);\n return;\n default:\n return;\n }\n\n e.preventDefault();\n if (newMonth < 0) {\n panelDate.value = new Date(panelDate.value.getFullYear() - 1, 12 + newMonth, 1);\n } else if (newMonth > 11) {\n panelDate.value = new Date(panelDate.value.getFullYear() + 1, newMonth - 12, 1);\n } else {\n panelDate.value = new Date(panelDate.value.getFullYear(), newMonth, 1);\n }\n}\n\nfunction handleYearKeydown(e: KeyboardEvent) {\n const currentYear = panelDate.value.getFullYear();\n let newYear = currentYear;\n\n switch (e.key) {\n case 'ArrowLeft':\n newYear = currentYear - 1;\n break;\n case 'ArrowRight':\n newYear = currentYear + 1;\n break;\n case 'ArrowUp':\n newYear = currentYear - 3;\n break;\n case 'ArrowDown':\n newYear = currentYear + 3;\n break;\n case 'Enter':\n case ' ':\n e.preventDefault();\n selectYear(currentYear);\n return;\n default:\n return;\n }\n\n e.preventDefault();\n panelDate.value = new Date(newYear, panelDate.value.getMonth(), 1);\n}\n\n// ─────────────────────────────────────────────\n// Computed panel mode checks\n// ─────────────────────────────────────────────\nconst showDateGrid = computed(() => panelMode.value === 'date' || panelMode.value === 'week');\nconst showMonthGrid = computed(() => panelMode.value === 'month');\nconst showYearGrid = computed(() => panelMode.value === 'year');\nconst showQuarterGrid = computed(() => panelMode.value === 'quarter');\n\n// ─────────────────────────────────────────────\n// Placeholder\n// ─────────────────────────────────────────────\nconst effectivePlaceholder = computed(() => {\n if (placeholder) return placeholder;\n const map: Record<string, string> = {\n date: 'Select date',\n week: 'Select week',\n month: 'Select month',\n quarter: 'Select quarter',\n year: 'Select year',\n };\n return map[picker] ?? 'Select date';\n});\n\n// ─────────────────────────────────────────────\n// Watch for controlled open\n// ─────────────────────────────────────────────\nwatch(\n () => open,\n (val) => {\n if (val !== undefined) {\n isPanelOpen.value = val;\n isOpen.value = val;\n if (val) {\n panelEl.value?.showPopover?.();\n } else {\n panelEl.value?.hidePopover?.();\n }\n }\n },\n);\n\nwatch(isPanelOpen, (val) => {\n if (val) {\n panelMode.value = picker;\n if (selectedDate.value) {\n panelDate.value = new Date(selectedDate.value);\n }\n }\n});\n</script>\n\n<template>\n <div\n class=\"b-date-picker\"\n :class=\"[\n `b-date-picker--${size}`,\n `b-date-picker--${variant}`,\n {\n 'b-date-picker--disabled': disabled,\n 'b-date-picker--focused': isPanelOpen,\n 'b-date-picker--clearable': allowClear && !!selectedDate && !disabled,\n 'b-date-picker--error': status === BDatePickerStatus.Error,\n 'b-date-picker--warning': status === BDatePickerStatus.Warning,\n },\n ]\"\n >\n <!-- Input trigger -->\n <div class=\"b-date-picker__input-wrap\" @click=\"togglePanel\">\n <input\n ref=\"inputEl\"\n class=\"b-date-picker__input\"\n type=\"text\"\n :value=\"inputText || displayValue\"\n :placeholder=\"effectivePlaceholder\"\n :disabled=\"disabled\"\n :readonly=\"inputReadOnly\"\n :aria-expanded=\"isPanelOpen\"\n aria-haspopup=\"dialog\"\n :aria-controls=\"isPanelOpen ? `b-date-picker-panel-${componentUID}` : undefined\"\n role=\"combobox\"\n autocomplete=\"off\"\n @input=\"handleInputChange\"\n @blur=\"handleInputBlur\"\n @keydown=\"handleInputKeydown\"\n />\n\n <!-- Clear button -->\n <button\n v-if=\"allowClear && selectedDate && !disabled\"\n class=\"b-date-picker__clear\"\n type=\"button\"\n aria-label=\"Clear date\"\n tabindex=\"-1\"\n @click=\"clearValue\"\n >\n <svg viewBox=\"0 0 16 16\" fill=\"currentColor\" aria-hidden=\"true\">\n <path\n d=\"M8 1a7 7 0 110 14A7 7 0 018 1zm2.828 4.172a.5.5 0 00-.707 0L8 7.293 5.879 5.172a.5.5 0 10-.707.707L7.293 8l-2.121 2.121a.5.5 0 10.707.707L8 8.707l2.121 2.121a.5.5 0 10.707-.707L8.707 8l2.121-2.121a.5.5 0 000-.707z\"\n />\n </svg>\n </button>\n\n <!-- Suffix icon -->\n <span class=\"b-date-picker__suffix\" aria-hidden=\"true\">\n <svg viewBox=\"0 0 16 16\" fill=\"currentColor\">\n <path\n d=\"M4.5 1a.5.5 0 01.5.5V2h6v-.5a.5.5 0 011 0V2h1.5A1.5 1.5 0 0115 3.5v10a1.5 1.5 0 01-1.5 1.5h-11A1.5 1.5 0 011 13.5v-10A1.5 1.5 0 012.5 2H4v-.5a.5.5 0 01.5-.5zM14 6H2v7.5a.5.5 0 00.5.5h11a.5.5 0 00.5-.5V6zm-1.5-3H12v.5a.5.5 0 01-1 0V3H5v.5a.5.5 0 01-1 0V3H2.5a.5.5 0 00-.5.5V5h12V3.5a.5.5 0 00-.5-.5z\"\n />\n </svg>\n </span>\n </div>\n\n <!-- Panel (Popover API) -->\n <div\n :id=\"`b-date-picker-panel-${componentUID}`\"\n ref=\"panelEl\"\n class=\"b-date-picker__panel\"\n popover\n role=\"dialog\"\n :aria-label=\"`${picker} picker`\"\n :aria-modal=\"true\"\n @toggle=\"handlePopoverToggle\"\n @keydown=\"handlePanelKeydown\"\n >\n <div class=\"b-date-picker__panel-inner\">\n <!-- Presets sidebar -->\n <div v-if=\"presets && presets.length\" class=\"b-date-picker__presets\">\n <button\n v-for=\"preset in presets\"\n :key=\"preset.label\"\n class=\"b-date-picker__preset-btn\"\n type=\"button\"\n @click=\"selectPreset(preset)\"\n >\n {{ preset.label }}\n </button>\n </div>\n\n <div class=\"b-date-picker__panel-main\">\n <!-- Header -->\n <div class=\"b-date-picker__header\">\n <button\n v-if=\"showDateGrid\"\n class=\"b-date-picker__nav-btn\"\n type=\"button\"\n aria-label=\"Previous year\"\n @click=\"prevYear\"\n >\n <svg viewBox=\"0 0 16 16\" fill=\"currentColor\" aria-hidden=\"true\">\n <path\n d=\"M9.354 3.354a.5.5 0 00-.708-.708l-5 5a.5.5 0 000 .708l5 5a.5.5 0 00.708-.708L4.707 8l4.647-4.646z\"\n />\n <path\n d=\"M12.354 3.354a.5.5 0 00-.708-.708l-5 5a.5.5 0 000 .708l5 5a.5.5 0 00.708-.708L7.707 8l4.647-4.646z\"\n />\n </svg>\n </button>\n <button\n v-if=\"showYearGrid\"\n class=\"b-date-picker__nav-btn\"\n type=\"button\"\n aria-label=\"Previous decade\"\n @click=\"prevDecade\"\n >\n <svg viewBox=\"0 0 16 16\" fill=\"currentColor\" aria-hidden=\"true\">\n <path\n d=\"M9.354 3.354a.5.5 0 00-.708-.708l-5 5a.5.5 0 000 .708l5 5a.5.5 0 00.708-.708L4.707 8l4.647-4.646z\"\n />\n <path\n d=\"M12.354 3.354a.5.5 0 00-.708-.708l-5 5a.5.5 0 000 .708l5 5a.5.5 0 00.708-.708L7.707 8l4.647-4.646z\"\n />\n </svg>\n </button>\n <button\n v-if=\"showDateGrid\"\n class=\"b-date-picker__nav-btn\"\n type=\"button\"\n aria-label=\"Previous month\"\n @click=\"prevMonth\"\n >\n <svg viewBox=\"0 0 16 16\" fill=\"currentColor\" aria-hidden=\"true\">\n <path\n d=\"M10.354 3.354a.5.5 0 00-.708-.708l-5 5a.5.5 0 000 .708l5 5a.5.5 0 00.708-.708L5.707 8l4.647-4.646z\"\n />\n </svg>\n </button>\n <button\n v-if=\"showMonthGrid || showQuarterGrid\"\n class=\"b-date-picker__nav-btn\"\n type=\"button\"\n aria-label=\"Previous year\"\n @click=\"prevYear\"\n >\n <svg viewBox=\"0 0 16 16\" fill=\"currentColor\" aria-hidden=\"true\">\n <path\n d=\"M10.354 3.354a.5.5 0 00-.708-.708l-5 5a.5.5 0 000 .708l5 5a.5.5 0 00.708-.708L5.707 8l4.647-4.646z\"\n />\n </svg>\n </button>\n\n <!-- Heading -->\n <button\n class=\"b-date-picker__heading\"\n type=\"button\"\n :aria-label=\"`Current view: ${panelHeading}`\"\n @click=\"\n switchPanelMode(\n panelMode === 'date' || panelMode === 'week'\n ? 'month'\n : panelMode === 'month' || panelMode === 'quarter'\n ? 'year'\n : 'year',\n )\n \"\n >\n {{ panelHeading }}\n </button>\n\n <button\n v-if=\"showDateGrid\"\n class=\"b-date-picker__nav-btn\"\n type=\"button\"\n aria-label=\"Next month\"\n @click=\"nextMonth\"\n >\n <svg viewBox=\"0 0 16 16\" fill=\"currentColor\" aria-hidden=\"true\">\n <path\n d=\"M5.646 3.354a.5.5 0 01.708-.708l5 5a.5.5 0 010 .708l-5 5a.5.5 0 01-.708-.708L10.293 8 5.646 3.354z\"\n />\n </svg>\n </button>\n <button\n v-if=\"showMonthGrid || showQuarterGrid\"\n class=\"b-date-picker__nav-btn\"\n type=\"button\"\n aria-label=\"Next year\"\n @click=\"nextYear\"\n >\n <svg viewBox=\"0 0 16 16\" fill=\"currentColor\" aria-hidden=\"true\">\n <path\n d=\"M5.646 3.354a.5.5 0 01.708-.708l5 5a.5.5 0 010 .708l-5 5a.5.5 0 01-.708-.708L10.293 8 5.646 3.354z\"\n />\n </svg>\n </button>\n <button\n v-if=\"showDateGrid\"\n class=\"b-date-picker__nav-btn\"\n type=\"button\"\n aria-label=\"Next year\"\n @click=\"nextYear\"\n >\n <svg viewBox=\"0 0 16 16\" fill=\"currentColor\" aria-hidden=\"true\">\n <path\n d=\"M5.646 3.354a.5.5 0 01.708-.708l5 5a.5.5 0 010 .708l-5 5a.5.5 0 01-.708-.708L10.293 8 5.646 3.354z\"\n />\n <path\n d=\"M2.646 3.354a.5.5 0 01.708-.708l5 5a.5.5 0 010 .708l-5 5a.5.5 0 01-.708-.708L7.293 8 2.646 3.354z\"\n />\n </svg>\n </button>\n <button\n v-if=\"showYearGrid\"\n class=\"b-date-picker__nav-btn\"\n type=\"button\"\n aria-label=\"Next decade\"\n @click=\"nextDecade\"\n >\n <svg viewBox=\"0 0 16 16\" fill=\"currentColor\" aria-hidden=\"true\">\n <path\n d=\"M5.646 3.354a.5.5 0 01.708-.708l5 5a.5.5 0 010 .708l-5 5a.5.5 0 01-.708-.708L10.293 8 5.646 3.354z\"\n />\n <path\n d=\"M2.646 3.354a.5.5 0 01.708-.708l5 5a.5.5 0 010 .708l-5 5a.5.5 0 01-.708-.708L7.293 8 2.646 3.354z\"\n />\n </svg>\n </button>\n </div>\n\n <!-- Date grid -->\n <div v-if=\"showDateGrid\" class=\"b-date-picker__body\" role=\"grid\" aria-label=\"Calendar\">\n <div class=\"b-date-picker__weekdays\" role=\"row\">\n <div\n v-if=\"showWeek\"\n class=\"b-date-picker__weekday b-date-picker__week-number-header\"\n role=\"columnheader\"\n aria-label=\"Week\"\n >\n #\n </div>\n <div\n v-for=\"day in weekdayLabels\"\n :key=\"day\"\n class=\"b-date-picker__weekday\"\n role=\"columnheader\"\n :aria-label=\"day\"\n >\n {{ day }}\n </div>\n </div>\n\n <div v-for=\"(row, rowIdx) in 6\" :key=\"rowIdx\" class=\"b-date-picker__row\" role=\"row\">\n <div v-if=\"showWeek\" class=\"b-date-picker__cell b-date-picker__week-number\">\n {{ getWeekNumber(calendarDates[rowIdx * 7].date) }}\n </div>\n <button\n v-for=\"(cell, colIdx) in calendarDates.slice(rowIdx * 7, rowIdx * 7 + 7)\"\n :key=\"colIdx\"\n class=\"b-date-picker__cell\"\n :class=\"{\n 'b-date-picker__cell--other': !cell.current,\n 'b-date-picker__cell--today': isToday(cell.date),\n 'b-date-picker__cell--selected': isSelected(cell.date),\n 'b-date-picker__cell--disabled': isDateDisabled(cell.date),\n 'b-date-picker__cell--hovered': hoveredDate && isSameDay(cell.date, hoveredDate),\n }\"\n type=\"button\"\n :aria-label=\"`${cell.date.getFullYear()}-${String(cell.date.getMonth() + 1).padStart(2, '0')}-${String(cell.date.getDate()).padStart(2, '0')}`\"\n :aria-selected=\"isSelected(cell.date)\"\n :aria-disabled=\"isDateDisabled(cell.date)\"\n :disabled=\"isDateDisabled(cell.date)\"\n :tabindex=\"isSameDay(cell.date, panelDate) ? 0 : -1\"\n @click=\"selectDate(cell.date)\"\n @mouseenter=\"hoveredDate = cell.date\"\n @mouseleave=\"hoveredDate = null\"\n >\n {{ cell.date.getDate() }}\n </button>\n </div>\n </div>\n\n <!-- Month grid -->\n <div\n v-if=\"showMonthGrid\"\n class=\"b-date-picker__body b-date-picker__grid-3x4\"\n role=\"grid\"\n aria-label=\"Month selection\"\n >\n <button\n v-for=\"item in calendarMonths\"\n :key=\"item.month\"\n class=\"b-date-picker__cell b-date-picker__cell--large\"\n :class=\"{\n 'b-date-picker__cell--selected':\n selectedDate &&\n selectedDate.getFullYear() === item.year &&\n selectedDate.getMonth() === item.month,\n 'b-date-picker__cell--current':\n new Date().getMonth() === item.month && new Date().getFullYear() === item.year,\n }\"\n type=\"button\"\n :aria-label=\"item.label\"\n :aria-selected=\"\n selectedDate?.getMonth() === item.month && selectedDate?.getFullYear() === item.year\n \"\n @click=\"selectMonth(item.month)\"\n >\n {{ item.label }}\n </button>\n </div>\n\n <!-- Year grid -->\n <div\n v-if=\"showYearGrid\"\n class=\"b-date-picker__body b-date-picker__grid-3x4\"\n role=\"grid\"\n aria-label=\"Year selection\"\n >\n <button\n v-for=\"item in calendarYears\"\n :key=\"item.year\"\n class=\"b-date-picker__cell b-date-picker__cell--large\"\n :class=\"{\n 'b-date-picker__cell--other': !item.current,\n 'b-date-picker__cell--selected':\n selectedDate && selectedDate.getFullYear() === item.year,\n 'b-date-picker__cell--current': new Date().getFullYear() === item.year,\n }\"\n type=\"button\"\n :aria-label=\"String(item.year)\"\n :aria-selected=\"selectedDate?.getFullYear() === item.year\"\n @click=\"selectYear(item.year)\"\n >\n {{ item.year }}\n </button>\n </div>\n\n <!-- Quarter grid -->\n <div\n v-if=\"showQuarterGrid\"\n class=\"b-date-picker__body b-date-picker__grid-2x2\"\n role=\"grid\"\n aria-label=\"Quarter selection\"\n >\n <button\n v-for=\"item in calendarQuarters\"\n :key=\"item.quarter\"\n class=\"b-date-picker__cell b-date-picker__cell--large\"\n :class=\"{\n 'b-date-picker__cell--selected':\n selectedDate &&\n Math.ceil((selectedDate.getMonth() + 1) / 3) === item.quarter &&\n selectedDate.getFullYear() === item.year,\n }\"\n type=\"button\"\n :aria-label=\"`Quarter ${item.quarter}`\"\n @click=\"selectQuarter(item.quarter)\"\n >\n {{ item.label }}\n </button>\n </div>\n\n <!-- Footer -->\n <div\n v-if=\"showNow && (panelMode === 'date' || panelMode === 'week')\"\n class=\"b-date-picker__footer\"\n >\n <button class=\"b-date-picker__today-btn\" type=\"button\" @click=\"selectToday\">\n {{ todayLabel }}\n </button>\n </div>\n </div>\n </div>\n </div>\n </div>\n</template>\n\n<style>\n.b-date-picker {\n --b-date-picker-active-bg: #ffffff;\n --b-date-picker-active-border-color: #1677ff;\n --b-date-picker-active-shadow: 0 0 0 2px rgba(5, 145, 255, 0.1);\n --b-date-picker-hover-bg: #ffffff;\n --b-date-picker-hover-border-color: #4096ff;\n --b-date-picker-cell-active-with-range-bg: #e6f4ff;\n --b-date-picker-cell-bg-disabled: rgba(0, 0, 0, 0.04);\n --b-date-picker-cell-height: 24px;\n --b-date-picker-cell-width: 36px;\n --b-date-picker-cell-hover-bg: rgba(0, 0, 0, 0.04);\n --b-date-picker-cell-hover-with-range-bg: #c8dfff;\n --b-date-picker-cell-range-border-color: #82b4f9;\n --b-date-picker-error-active-shadow: 0 0 0 2px rgba(255, 38, 5, 0.06);\n --b-date-picker-warning-active-shadow: 0 0 0 2px rgba(255, 215, 5, 0.1);\n --b-date-picker-input-font-size: 14px;\n --b-date-picker-input-font-size-lg: 16px;\n --b-date-picker-input-font-size-sm: 12px;\n --b-date-picker-padding-block: 4px;\n --b-date-picker-padding-block-lg: 7px;\n --b-date-picker-padding-block-sm: 0px;\n --b-date-picker-padding-inline: 11px;\n --b-date-picker-padding-inline-lg: 11px;\n --b-date-picker-padding-inline-sm: 7px;\n --b-date-picker-presets-width: 120px;\n --b-date-picker-presets-max-width: 200px;\n --b-date-picker-text-height: 40px;\n --b-date-picker-without-time-cell-height: 66px;\n --b-date-picker-z-index-popup: 1050;\n --b-date-picker-bg: #ffffff;\n --b-date-picker-border-color: #d9d9d9;\n --b-date-picker-border-radius: 6px;\n --b-date-picker-text-color: rgba(0, 0, 0, 0.88);\n --b-date-picker-text-color-secondary: rgba(0, 0, 0, 0.45);\n --b-date-picker-text-color-disabled: rgba(0, 0, 0, 0.25);\n --b-date-picker-panel-bg: #ffffff;\n --b-date-picker-panel-shadow:\n 0 6px 16px 0 rgba(0, 0, 0, 0.08), 0 3px 6px -4px rgba(0, 0, 0, 0.12),\n 0 9px 28px 8px rgba(0, 0, 0, 0.05);\n --b-date-picker-selected-bg: #1677ff;\n --b-date-picker-selected-color: #ffffff;\n --b-date-picker-today-border-color: #1677ff;\n --b-date-picker-transition-duration: 200ms;\n\n position: relative;\n display: inline-flex;\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\n font-size: var(--b-date-picker-input-font-size);\n color: var(--b-date-picker-text-color);\n}\n\n.b-date-picker--sm .b-date-picker__input-wrap {\n height: 24px;\n padding: var(--b-date-picker-padding-block-sm) var(--b-date-picker-padding-inline-sm);\n font-size: var(--b-date-picker-input-font-size-sm);\n}\n.b-date-picker--md .b-date-picker__input-wrap {\n height: 32px;\n padding: var(--b-date-picker-padding-block) var(--b-date-picker-padding-inline);\n font-size: var(--b-date-picker-input-font-size);\n}\n.b-date-picker--lg .b-date-picker__input-wrap {\n height: 40px;\n padding: var(--b-date-picker-padding-block-lg) var(--b-date-picker-padding-inline-lg);\n font-size: var(--b-date-picker-input-font-size-lg);\n}\n\n.b-date-picker__input-wrap {\n display: flex;\n align-items: center;\n gap: 4px;\n width: 100%;\n min-width: 120px;\n background: var(--b-date-picker-bg);\n border: 1px solid var(--b-date-picker-border-color);\n border-radius: var(--b-date-picker-border-radius);\n cursor: pointer;\n transition:\n border-color var(--b-date-picker-transition-duration),\n box-shadow var(--b-date-picker-transition-duration);\n anchor-name: v-bind('anchorName');\n}\n\n.b-date-picker__input-wrap:hover:not(.b-date-picker--disabled .b-date-picker__input-wrap) {\n border-color: var(--b-date-picker-hover-border-color);\n background: var(--b-date-picker-hover-bg);\n}\n\n.b-date-picker--focused .b-date-picker__input-wrap {\n border-color: var(--b-date-picker-active-border-color);\n box-shadow: var(--b-date-picker-active-shadow);\n background: var(--b-date-picker-active-bg);\n}\n\n.b-date-picker--filled .b-date-picker__input-wrap {\n background: rgba(0, 0, 0, 0.04);\n border-color: transparent;\n}\n.b-date-picker--filled.b-date-picker--focused .b-date-picker__input-wrap {\n background: var(--b-date-picker-active-bg);\n border-color: var(--b-date-picker-active-border-color);\n}\n\n.b-date-picker--borderless .b-date-picker__input-wrap {\n border-color: transparent;\n box-shadow: none;\n}\n.b-date-picker--borderless.b-date-picker--focused .b-date-picker__input-wrap {\n box-shadow: none;\n}\n\n.b-date-picker--underlined .b-date-picker__input-wrap {\n border-radius: 0;\n border: none;\n border-bottom: 1px solid var(--b-date-picker-border-color);\n}\n.b-date-picker--underlined.b-date-picker--focused .b-date-picker__input-wrap {\n border-bottom-color: var(--b-date-picker-active-border-color);\n box-shadow: none;\n}\n\n.b-date-picker--error .b-date-picker__input-wrap {\n border-color: #ff4d4f;\n}\n.b-date-picker--error.b-date-picker--focused .b-date-picker__input-wrap {\n box-shadow: var(--b-date-picker-error-active-shadow);\n}\n.b-date-picker--warning .b-date-picker__input-wrap {\n border-color: #faad14;\n}\n.b-date-picker--warning.b-date-picker--focused .b-date-picker__input-wrap {\n box-shadow: var(--b-date-picker-warning-active-shadow);\n}\n\n.b-date-picker--disabled .b-date-picker__input-wrap {\n background: rgba(0, 0, 0, 0.04);\n cursor: not-allowed;\n opacity: 0.6;\n}\n\n.b-date-picker__input {\n flex: 1;\n border: none;\n outline: none;\n background: transparent;\n font: inherit;\n color: inherit;\n cursor: inherit;\n min-width: 0;\n}\n.b-date-picker__input::placeholder {\n color: var(--b-date-picker-text-color-secondary);\n}\n\n.b-date-picker__suffix {\n display: flex;\n align-items: center;\n color: var(--b-date-picker-text-color-secondary);\n flex-shrink: 0;\n}\n.b-date-picker__suffix svg {\n width: 14px;\n height: 14px;\n}\n\n.b-date-picker__clear {\n display: flex;\n align-items: center;\n justify-content: center;\n border: none;\n background: transparent;\n color: var(--b-date-picker-text-color-secondary);\n cursor: pointer;\n padding: 0;\n opacity: 0;\n transition: opacity var(--b-date-picker-transition-duration);\n}\n.b-date-picker__clear svg {\n width: 14px;\n height: 14px;\n}\n.b-date-picker--clearable:hover .b-date-picker__clear {\n opacity: 1;\n}\n.b-date-picker--clearable:hover .b-date-picker__suffix {\n opacity: 0;\n}\n.b-date-picker--clearable:not(:hover) .b-date-picker__suffix {\n opacity: 1;\n}\n\n.b-date-picker__panel {\n position: absolute;\n margin: 0;\n border: none;\n padding: 0;\n background: transparent;\n overflow: visible;\n z-index: var(--b-date-picker-z-index-popup);\n\n position-anchor: v-bind('anchorName');\n inset: auto;\n top: anchor(bottom);\n left: anchor(left);\n margin-top: 4px;\n\n opacity: 0;\n transform: translateY(-4px);\n transition:\n opacity var(--b-date-picker-transition-duration),\n transform var(--b-date-picker-transition-duration),\n display var(--b-date-picker-transition-duration);\n transition-behavior: allow-discrete;\n}\n\n.b-date-picker__panel:popover-open {\n opacity: 1;\n transform: translateY(0);\n\n @starting-style {\n opacity: 0;\n transform: translateY(-4px);\n }\n}\n\n.b-date-picker__panel-inner {\n display: flex;\n background: var(--b-date-picker-panel-bg);\n border-radius: var(--b-date-picker-border-radius);\n box-shadow: var(--b-date-picker-panel-shadow);\n}\n\n.b-date-picker__presets {\n display: flex;\n flex-direction: column;\n gap: 4px;\n padding: 8px;\n border-right: 1px solid rgba(0, 0, 0, 0.06);\n min-width: var(--b-date-picker-presets-width);\n max-width: var(--b-date-picker-presets-max-width);\n}\n.b-date-picker__preset-btn {\n padding: 4px 8px;\n border: none;\n border-radius: 4px;\n background: transparent;\n text-align: left;\n cursor: pointer;\n font-size: 14px;\n color: var(--b-date-picker-text-color);\n white-space: nowrap;\n transition: background var(--b-date-picker-transition-duration);\n}\n.b-date-picker__preset-btn:hover {\n background: var(--b-date-picker-cell-hover-bg);\n}\n\n.b-date-picker__panel-main {\n padding: 8px;\n min-width: 280px;\n}\n\n.b-date-picker__header {\n display: flex;\n align-items: center;\n padding: 0 4px 8px;\n}\n.b-date-picker__nav-btn {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 24px;\n height: 24px;\n border: none;\n border-radius: 4px;\n background: transparent;\n cursor: pointer;\n color: var(--b-date-picker-text-color-secondary);\n transition:\n color var(--b-date-picker-transition-duration),\n background var(--b-date-picker-transition-duration);\n}\n.b-date-picker__nav-btn:hover {\n color: var(--b-date-picker-text-color);\n background: var(--b-date-picker-cell-hover-bg);\n}\n.b-date-picker__nav-btn svg {\n width: 12px;\n height: 12px;\n}\n.b-date-picker__heading {\n flex: 1;\n text-align: center;\n border: none;\n background: transparent;\n font-weight: 600;\n font-size: 14px;\n cursor: pointer;\n color: var(--b-date-picker-text-color);\n padding: 4px 8px;\n border-radius: 4px;\n transition: background var(--b-date-picker-transition-duration);\n}\n.b-date-picker__heading:hover {\n background: var(--b-date-picker-cell-hover-bg);\n}\n\n.b-date-picker__body {\n border-top: 1px solid rgba(0, 0, 0, 0.06);\n padding-top: 4px;\n}\n\n.b-date-picker__weekdays {\n display: grid;\n grid-template-columns: repeat(7, 1fr);\n text-align: center;\n}\n.b-date-picker__weekdays:has(.b-date-picker__week-number-header) {\n grid-template-columns: 32px repeat(7, 1fr);\n}\n.b-date-picker__weekday {\n padding: 4px 0;\n font-size: 12px;\n font-weight: 500;\n color: var(--b-date-picker-text-color-secondary);\n}\n.b-date-picker__week-number-header {\n color: var(--b-date-picker-text-color-disabled);\n}\n\n.b-date-picker__row {\n display: grid;\n grid-template-columns: repeat(7, 1fr);\n}\n.b-date-picker__row:has(.b-date-picker__week-number) {\n grid-template-columns: 32px repeat(7, 1fr);\n}\n.b-date-picker__week-number {\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 12px;\n color: var(--b-date-picker-text-color-disabled);\n}\n\n.b-date-picker__cell {\n display: flex;\n align-items: center;\n justify-content: center;\n width: var(--b-date-picker-cell-width);\n height: var(--b-date-picker-cell-height);\n margin: 2px auto;\n border: none;\n border-radius: 4px;\n background: transparent;\n font-size: 14px;\n cursor: pointer;\n color: var(--b-date-picker-text-color);\n transition:\n background var(--b-date-picker-transition-duration),\n color var(--b-date-picker-transition-duration);\n}\n.b-date-picker__cell:hover:not(:disabled) {\n background: var(--b-date-picker-cell-hover-bg);\n}\n.b-date-picker__cell--other {\n color: var(--b-date-picker-text-color-disabled);\n}\n.b-date-picker__cell--today {\n border: 1px solid var(--b-date-picker-today-border-color);\n}\n.b-date-picker__cell--selected {\n background: var(--b-date-picker-selected-bg) !important;\n color: var(--b-date-picker-selected-color) !important;\n}\n.b-date-picker__cell--disabled {\n color: var(--b-date-picker-text-color-disabled);\n background: var(--b-date-picker-cell-bg-disabled);\n cursor: not-allowed;\n}\n.b-date-picker__cell--current {\n border: 1px solid var(--b-date-picker-today-border-color);\n}\n.b-date-picker__cell--large {\n width: auto;\n height: var(--b-date-picker-without-time-cell-height);\n padding: 8px 12px;\n}\n\n.b-date-picker__grid-3x4 {\n display: grid;\n grid-template-columns: repeat(3, 1fr);\n gap: 4px;\n}\n.b-date-picker__grid-2x2 {\n display: grid;\n grid-template-columns: repeat(2, 1fr);\n gap: 8px;\n}\n\n.b-date-picker__footer {\n display: flex;\n justify-content: center;\n padding-top: 8px;\n border-top: 1px solid rgba(0, 0, 0, 0.06);\n margin-top: 4px;\n}\n.b-date-picker__today-btn {\n border: none;\n background: transparent;\n color: var(--b-date-picker-active-border-color);\n cursor: pointer;\n font-size: 14px;\n padding: 4px 8px;\n border-radius: 4px;\n transition: background var(--b-date-picker-transition-duration);\n}\n.b-date-picker__today-btn:hover {\n background: var(--b-date-picker-cell-hover-bg);\n}\n\n[data-prefers-color='dark'] .b-date-picker {\n --b-date-picker-bg: #141414;\n --b-date-picker-panel-bg: #1f1f1f;\n --b-date-picker-border-color: #424242;\n --b-date-picker-text-color: rgba(255, 255, 255, 0.88);\n --b-date-picker-text-color-secondary: rgba(255, 255, 255, 0.45);\n --b-date-picker-text-color-disabled: rgba(255, 255, 255, 0.25);\n --b-date-picker-hover-border-color: #3c89e8;\n --b-date-picker-active-border-color: #1668dc;\n --b-date-picker-active-shadow: 0 0 0 2px rgba(22, 104, 220, 0.15);\n --b-date-picker-cell-hover-bg: rgba(255, 255, 255, 0.08);\n --b-date-picker-cell-bg-disabled: rgba(255, 255, 255, 0.08);\n --b-date-picker-selected-bg: #1668dc;\n --b-date-picker-today-border-color: #1668dc;\n --b-date-picker-panel-shadow:\n 0 6px 16px 0 rgba(0, 0, 0, 0.32), 0 3px 6px -4px rgba(0, 0, 0, 0.48),\n 0 9px 28px 8px rgba(0, 0, 0, 0.2);\n --b-date-picker-hover-bg: #141414;\n --b-date-picker-active-bg: #141414;\n}\n\n@media (prefers-color-scheme: dark) {\n [data-prefers-color='system'] .b-date-picker {\n --b-date-picker-bg: #141414;\n --b-date-picker-panel-bg: #1f1f1f;\n --b-date-picker-border-color: #424242;\n --b-date-picker-text-color: rgba(255, 255, 255, 0.88);\n --b-date-picker-text-color-secondary: rgba(255, 255, 255, 0.45);\n --b-date-picker-text-color-disabled: rgba(255, 255, 255, 0.25);\n --b-date-picker-hover-border-color: #3c89e8;\n --b-date-picker-active-border-color: #1668dc;\n --b-date-picker-active-shadow: 0 0 0 2px rgba(22, 104, 220, 0.15);\n --b-date-picker-cell-hover-bg: rgba(255, 255, 255, 0.08);\n --b-date-picker-cell-bg-disabled: rgba(255, 255, 255, 0.08);\n --b-date-picker-selected-bg: #1668dc;\n --b-date-picker-today-border-color: #1668dc;\n --b-date-picker-panel-shadow:\n 0 6px 16px 0 rgba(0, 0, 0, 0.32), 0 3px 6px -4px rgba(0, 0, 0, 0.48),\n 0 9px 28px 8px rgba(0, 0, 0, 0.2);\n --b-date-picker-hover-bg: #141414;\n --b-date-picker-active-bg: #141414;\n }\n}\n\n@media (prefers-reduced-motion: reduce) {\n .b-date-picker,\n .b-date-picker__panel,\n .b-date-picker__cell,\n .b-date-picker__input-wrap,\n .b-date-picker__clear,\n .b-date-picker__nav-btn,\n .b-date-picker__heading,\n .b-date-picker__preset-btn,\n .b-date-picker__today-btn {\n transition-duration: 0ms !important;\n }\n}\n</style>\n"],"mappings":""}
|
|
1
|
+
{"version":3,"file":"design-system72.js","names":[],"sources":["../src/components/BDatePicker/types.ts"],"sourcesContent":["export enum BDatePickerType {\n Date = 'date',\n Week = 'week',\n Month = 'month',\n Quarter = 'quarter',\n Year = 'year',\n}\n\nexport enum BDatePickerSize {\n Small = 'sm',\n Medium = 'md',\n Large = 'lg',\n}\n\nexport enum BDatePickerVariant {\n Outlined = 'outlined',\n Filled = 'filled',\n Borderless = 'borderless',\n Underlined = 'underlined',\n}\n\nexport enum BDatePickerStatus {\n Error = 'error',\n Warning = 'warning',\n}\n\nexport enum BDatePickerPlacement {\n BottomLeft = 'bottom-left',\n BottomRight = 'bottom-right',\n TopLeft = 'top-left',\n TopRight = 'top-right',\n}\n\nexport interface BDatePickerPreset {\n label: string;\n value: Date | (() => Date);\n}\n\nexport interface BDatePickerDisabledDateInfo {\n type: `${BDatePickerType}`;\n}\n"],"mappings":";AAAA,IAAY,IAAL,yBAAA,GAAA;QACL,EAAA,OAAA,QACA,EAAA,OAAA,QACA,EAAA,QAAA,SACA,EAAA,UAAA,WACA,EAAA,OAAA;KACD,EAEW,IAAL,yBAAA,GAAA;QACL,EAAA,QAAA,MACA,EAAA,SAAA,MACA,EAAA,QAAA;KACD,EAEW,IAAL,yBAAA,GAAA;QACL,EAAA,WAAA,YACA,EAAA,SAAA,UACA,EAAA,aAAA,cACA,EAAA,aAAA;KACD,EAEW,IAAL,yBAAA,GAAA;QACL,EAAA,QAAA,SACA,EAAA,UAAA;KACD,EAEW,IAAL,yBAAA,GAAA;QACL,EAAA,aAAA,eACA,EAAA,cAAA,gBACA,EAAA,UAAA,YACA,EAAA,WAAA;KACD"}
|