@ixfx/components 0.6.0 → 0.6.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (50) hide show
  1. package/bundle/index.d.ts +176 -1
  2. package/bundle/index.d.ts.map +1 -1
  3. package/bundle/index.js +810 -1
  4. package/bundle/index.js.map +1 -1
  5. package/dist/ac-text.d.ts +1 -1
  6. package/dist/{ac-token-DVbmHmky.d.ts → ac-token-BAa6ke09.d.ts} +2 -2
  7. package/dist/{ac-token-DVbmHmky.d.ts.map → ac-token-BAa6ke09.d.ts.map} +1 -1
  8. package/dist/ac-token.d.ts +1 -1
  9. package/dist/colour-picker.d.ts +1 -1
  10. package/dist/crumbs.d.ts +1 -1
  11. package/dist/{data-grid-BeAkORz2.d.ts → data-grid-C8qIo1-u.d.ts} +2 -2
  12. package/dist/{data-grid-BeAkORz2.d.ts.map → data-grid-C8qIo1-u.d.ts.map} +1 -1
  13. package/dist/data-grid.d.ts +1 -1
  14. package/dist/{grouped-item-lister-CNLMgdIr.d.ts → grouped-item-lister-_pMDwIo1.d.ts} +2 -2
  15. package/dist/{grouped-item-lister-CNLMgdIr.d.ts.map → grouped-item-lister-_pMDwIo1.d.ts.map} +1 -1
  16. package/dist/grouped-item-lister.d.ts +1 -1
  17. package/dist/{icon-BUwP1CZ1.d.ts → icon-DpA9x2Ve.d.ts} +2 -2
  18. package/dist/icon-DpA9x2Ve.d.ts.map +1 -0
  19. package/dist/icons.d.ts +2 -2
  20. package/dist/{index-RqMh1i-O.d.ts → index-BtGFYfaK.d.ts} +2 -2
  21. package/dist/{index-RqMh1i-O.d.ts.map → index-BtGFYfaK.d.ts.map} +1 -1
  22. package/dist/{index-ovq_GTdl.d.ts → index-CKtLhgYj.d.ts} +3 -3
  23. package/dist/{index-ovq_GTdl.d.ts.map → index-CKtLhgYj.d.ts.map} +1 -1
  24. package/dist/{index-BUB5SICW.d.ts → index-CoqtMSd9.d.ts} +2 -2
  25. package/dist/{index-BUB5SICW.d.ts.map → index-CoqtMSd9.d.ts.map} +1 -1
  26. package/dist/{index-BOUaDIW-.d.ts → index-tq6f8007.d.ts} +2 -2
  27. package/dist/{index-BOUaDIW-.d.ts.map → index-tq6f8007.d.ts.map} +1 -1
  28. package/dist/index.d.ts +186 -11
  29. package/dist/index.d.ts.map +1 -1
  30. package/dist/index.js +811 -1
  31. package/dist/index.js.map +1 -1
  32. package/dist/{labelled-input-base-Dp_9KP0G.d.ts → labelled-input-base-DiTme1JO.d.ts} +2 -2
  33. package/dist/{labelled-input-base-Dp_9KP0G.d.ts.map → labelled-input-base-DiTme1JO.d.ts.map} +1 -1
  34. package/dist/labelled-radial-input.d.ts +2 -2
  35. package/dist/labelled-radial-input.d.ts.map +1 -1
  36. package/dist/labelled-range-input.d.ts +1 -1
  37. package/dist/{menu-item-BG5w7fi4.d.ts → menu-item-Bs2MYyHq.d.ts} +2 -2
  38. package/dist/{menu-item-BG5w7fi4.d.ts.map → menu-item-Bs2MYyHq.d.ts.map} +1 -1
  39. package/dist/menu.d.ts +2 -2
  40. package/dist/panel.d.ts +1 -1
  41. package/dist/{tab-list-Beuh2nom.d.ts → tab-list-D_1cYhB_.d.ts} +2 -2
  42. package/dist/{tab-list-Beuh2nom.d.ts.map → tab-list-D_1cYhB_.d.ts.map} +1 -1
  43. package/dist/tabs.d.ts +1 -1
  44. package/docs-user/README.md +1 -0
  45. package/docs-user/index.json +7 -2
  46. package/docs-user/llms.txt +1 -0
  47. package/docs-user/toolbar.md +135 -0
  48. package/llms.txt +1 -0
  49. package/package.json +2 -1
  50. package/dist/icon-BUwP1CZ1.d.ts.map +0 -1
package/dist/index.js CHANGED
@@ -55,6 +55,7 @@ import { customElement, eventOptions, property, query, queryAssignedElements, st
55
55
  import { unsafeHTML } from "lit/directives/unsafe-html.js";
56
56
  import { Trees } from "@ixfx/collections";
57
57
  import { clamper, scaler } from "@ixfx/numbers";
58
+ import { repeat } from "lit/directives/repeat.js";
58
59
  import { classMap } from "lit/directives/class-map.js";
59
60
  //#region src/button/radio-group.ts
60
61
  let RadioGroup = class RadioGroup extends LitElement {
@@ -3629,6 +3630,431 @@ __decorate([property({ type: String })], RatingElement.prototype, "variant", voi
3629
3630
  __decorate([state()], RatingElement.prototype, "_preview", void 0);
3630
3631
  RatingElement = __decorate([customElement(`ixfx-rating`)], RatingElement);
3631
3632
  //#endregion
3633
+ //#region src/sliding-number/sliding-number.ts
3634
+ const REEL_DIGITS = Array.from({ length: 30 }, (_, index) => index % 10);
3635
+ const SECTION_RANK = {
3636
+ lead: 0,
3637
+ integer: 1,
3638
+ decimal: 2,
3639
+ fraction: 3,
3640
+ trail: 4
3641
+ };
3642
+ function mod(n, m) {
3643
+ return (n % m + m) % m;
3644
+ }
3645
+ /** Parse a CSS time token (`0.7s`, `700ms`, `0`) to milliseconds. */
3646
+ function millis(value) {
3647
+ const s = value.trim();
3648
+ if (s === ``) return 0;
3649
+ if (s.endsWith(`ms`)) return Number.parseFloat(s) || 0;
3650
+ if (s.endsWith(`s`)) return (Number.parseFloat(s) || 0) * 1e3;
3651
+ return Number.parseFloat(s) || 0;
3652
+ }
3653
+ let SlidingNumberElement = class SlidingNumberElement extends LitElement {
3654
+ constructor(..._args) {
3655
+ super(..._args);
3656
+ this.value = 0;
3657
+ this.prefix = ``;
3658
+ this.suffix = ``;
3659
+ this.trend = `auto`;
3660
+ this.noAnimate = false;
3661
+ this.respectMotionPreference = true;
3662
+ this._cells = [];
3663
+ this._formatted = ``;
3664
+ this._ready = false;
3665
+ this._pendingSpins = [];
3666
+ this._pendingDir = `none`;
3667
+ this._reelAnims = /* @__PURE__ */ new Map();
3668
+ this._reapTimer = 0;
3669
+ }
3670
+ connectedCallback() {
3671
+ super.connectedCallback();
3672
+ if (!this.hasAttribute(`role`)) this.setAttribute(`role`, `img`);
3673
+ }
3674
+ disconnectedCallback() {
3675
+ super.disconnectedCallback();
3676
+ for (const anim of this._reelAnims.values()) anim.cancel();
3677
+ this._reelAnims.clear();
3678
+ if (this._reapTimer) clearTimeout(this._reapTimer);
3679
+ }
3680
+ _motionOK() {
3681
+ if (this.noAnimate) return false;
3682
+ if (this.respectMotionPreference && typeof window !== `undefined` && window.matchMedia?.(`(prefers-reduced-motion: reduce)`).matches) return false;
3683
+ return true;
3684
+ }
3685
+ _timing(kind) {
3686
+ const cs = getComputedStyle(this);
3687
+ return {
3688
+ duration: this._motionOK() ? millis(cs.getPropertyValue(`--sliding-number-${kind}-duration`)) : 0,
3689
+ easing: cs.getPropertyValue(`--sliding-number-${kind}-easing`).trim() || `ease`
3690
+ };
3691
+ }
3692
+ _numberFormat() {
3693
+ try {
3694
+ return new Intl.NumberFormat(this.locales || void 0, this.format || void 0);
3695
+ } catch {
3696
+ return new Intl.NumberFormat(this.locales || void 0);
3697
+ }
3698
+ }
3699
+ _resolveDir(first) {
3700
+ switch (this.trend) {
3701
+ case `up`:
3702
+ case `increasing`: return `up`;
3703
+ case `down`:
3704
+ case `decreasing`: return `down`;
3705
+ case `none`: return `none`;
3706
+ default:
3707
+ if (first || this._prevValue === void 0 || this.value === this._prevValue) return `none`;
3708
+ return this.value > this._prevValue ? `up` : `down`;
3709
+ }
3710
+ }
3711
+ /** Split the formatted value into positioned cells. */
3712
+ _buildCells(parts) {
3713
+ const intRaw = [];
3714
+ const fractionChars = [];
3715
+ const lead = [];
3716
+ const trail = [];
3717
+ let decimalChar = ``;
3718
+ let sawInteger = false;
3719
+ let sawDecimal = false;
3720
+ for (const part of parts) switch (part.type) {
3721
+ case `integer`:
3722
+ sawInteger = true;
3723
+ for (const c of part.value) intRaw.push({
3724
+ digit: true,
3725
+ char: c
3726
+ });
3727
+ break;
3728
+ case `group`:
3729
+ intRaw.push({
3730
+ digit: false,
3731
+ char: part.value
3732
+ });
3733
+ break;
3734
+ case `decimal`:
3735
+ sawDecimal = true;
3736
+ decimalChar = part.value;
3737
+ break;
3738
+ case `fraction`:
3739
+ for (const c of part.value) fractionChars.push(c);
3740
+ break;
3741
+ default: (sawInteger || sawDecimal ? trail : lead).push(part.value);
3742
+ }
3743
+ const cells = [];
3744
+ const totalIntDigits = intRaw.filter((x) => x.digit).length;
3745
+ lead.forEach((char, index) => {
3746
+ cells.push({
3747
+ key: `lead:${index}`,
3748
+ kind: `symbol`,
3749
+ section: `lead`,
3750
+ char,
3751
+ pos: index - 100,
3752
+ phase: `active`
3753
+ });
3754
+ });
3755
+ let seen = 0;
3756
+ for (const item of intRaw) if (item.digit) {
3757
+ const place = totalIntDigits - 1 - seen;
3758
+ seen++;
3759
+ cells.push({
3760
+ key: `int:${place}`,
3761
+ kind: `digit`,
3762
+ section: `integer`,
3763
+ char: item.char,
3764
+ pos: -place,
3765
+ phase: `active`
3766
+ });
3767
+ } else {
3768
+ const place = totalIntDigits - seen;
3769
+ cells.push({
3770
+ key: `grp:${place}`,
3771
+ kind: `symbol`,
3772
+ section: `integer`,
3773
+ char: item.char,
3774
+ pos: -place + .5,
3775
+ phase: `active`
3776
+ });
3777
+ }
3778
+ if (sawDecimal) cells.push({
3779
+ key: `decimal`,
3780
+ kind: `symbol`,
3781
+ section: `decimal`,
3782
+ char: decimalChar,
3783
+ pos: 0,
3784
+ phase: `active`
3785
+ });
3786
+ fractionChars.forEach((char, index) => {
3787
+ cells.push({
3788
+ key: `frac:${index}`,
3789
+ kind: `digit`,
3790
+ section: `fraction`,
3791
+ char,
3792
+ pos: index + 1,
3793
+ phase: `active`
3794
+ });
3795
+ });
3796
+ trail.forEach((char, index) => {
3797
+ cells.push({
3798
+ key: `trail:${index}`,
3799
+ kind: `symbol`,
3800
+ section: `trail`,
3801
+ char,
3802
+ pos: index + 100,
3803
+ phase: `active`
3804
+ });
3805
+ });
3806
+ return cells;
3807
+ }
3808
+ willUpdate(changed) {
3809
+ if (![
3810
+ `value`,
3811
+ `format`,
3812
+ `locales`,
3813
+ `prefix`,
3814
+ `suffix`,
3815
+ `noAnimate`
3816
+ ].some((p) => changed.has(p)) && this._ready) return;
3817
+ const nf = this._numberFormat();
3818
+ this._formatted = `${this.prefix}${nf.format(this.value)}${this.suffix}`;
3819
+ this.setAttribute(`aria-label`, this._formatted);
3820
+ this.toggleAttribute(`data-static`, !this._motionOK());
3821
+ const first = !this._ready;
3822
+ const motionOK = this._motionOK() && !first;
3823
+ const next = this._buildCells(nf.formatToParts(this.value));
3824
+ const nextKeys = new Set(next.map((c) => c.key));
3825
+ const prev = this._cells.filter((c) => c.phase !== `leave`);
3826
+ const prevByKey = new Map(prev.map((c) => [c.key, c]));
3827
+ const dir = this._resolveDir(first);
3828
+ const spins = [];
3829
+ const merged = [];
3830
+ for (const cell of next) {
3831
+ const before = prevByKey.get(cell.key);
3832
+ if (before) {
3833
+ if (motionOK && cell.kind === `digit` && before.char !== cell.char) spins.push({
3834
+ key: cell.key,
3835
+ from: Number(before.char),
3836
+ to: Number(cell.char)
3837
+ });
3838
+ merged.push({
3839
+ ...cell,
3840
+ phase: `active`
3841
+ });
3842
+ } else merged.push({
3843
+ ...cell,
3844
+ phase: motionOK ? `enter` : `active`
3845
+ });
3846
+ }
3847
+ if (motionOK) {
3848
+ for (const cell of prev) if (!nextKeys.has(cell.key)) merged.push({
3849
+ ...cell,
3850
+ phase: `leave`
3851
+ });
3852
+ }
3853
+ merged.sort((a, b) => SECTION_RANK[a.section] - SECTION_RANK[b.section] || a.pos - b.pos);
3854
+ this._cells = merged;
3855
+ this._pendingSpins = spins;
3856
+ this._pendingDir = dir;
3857
+ }
3858
+ updated() {
3859
+ for (const spin of this._pendingSpins) this._spin(spin.key, spin.from, spin.to, this._pendingDir);
3860
+ this._pendingSpins = [];
3861
+ if (this._cells.some((c) => c.phase === `enter`)) requestAnimationFrame(() => requestAnimationFrame(() => {
3862
+ let changed = false;
3863
+ for (const cell of this._cells) if (cell.phase === `enter`) {
3864
+ cell.phase = `active`;
3865
+ changed = true;
3866
+ }
3867
+ if (changed) {
3868
+ this._cells = [...this._cells];
3869
+ this.requestUpdate();
3870
+ }
3871
+ }));
3872
+ if (this._cells.some((c) => c.phase === `leave`)) {
3873
+ if (this._reapTimer) clearTimeout(this._reapTimer);
3874
+ this._reapTimer = window.setTimeout(() => {
3875
+ this._reapTimer = 0;
3876
+ const kept = this._cells.filter((c) => c.phase !== `leave`);
3877
+ if (kept.length !== this._cells.length) {
3878
+ this._cells = kept;
3879
+ this.requestUpdate();
3880
+ }
3881
+ }, this._timing(`transform`).duration + 120);
3882
+ }
3883
+ this._prevValue = this.value;
3884
+ this._ready = true;
3885
+ }
3886
+ _spin(key, fromDigit, toDigit, dir) {
3887
+ const reel = this.renderRoot.querySelector(`[data-key="${key}"] .reel`);
3888
+ if (!reel) return;
3889
+ const fromOffset = 10 + fromDigit;
3890
+ let toOffset;
3891
+ if (dir === `up`) toOffset = fromOffset + mod(toDigit - fromDigit, 10);
3892
+ else if (dir === `down`) toOffset = fromOffset - mod(fromDigit - toDigit, 10);
3893
+ else toOffset = [
3894
+ toDigit,
3895
+ 10 + toDigit,
3896
+ 20 + toDigit
3897
+ ].reduce((best, candidate) => Math.abs(candidate - fromOffset) < Math.abs(best - fromOffset) ? candidate : best);
3898
+ const { duration, easing } = this._timing(`spin`);
3899
+ this._reelAnims.get(key)?.cancel();
3900
+ if (duration === 0) {
3901
+ reel.style.setProperty(`--o`, String(10 + toDigit));
3902
+ return;
3903
+ }
3904
+ const anim = reel.animate([{ transform: `translateY(calc(-1em * ${fromOffset}))` }, { transform: `translateY(calc(-1em * ${toOffset}))` }], {
3905
+ duration,
3906
+ easing,
3907
+ fill: `both`
3908
+ });
3909
+ this._reelAnims.set(key, anim);
3910
+ anim.finished.then(() => {
3911
+ reel.style.setProperty(`--o`, String(10 + toDigit));
3912
+ anim.cancel();
3913
+ this._reelAnims.delete(key);
3914
+ }).catch(() => {});
3915
+ }
3916
+ _renderCell(cell) {
3917
+ if (cell.kind === `digit`) return html`
3918
+ <span class="cell digit" part="digit" data-key=${cell.key} data-phase=${cell.phase}>
3919
+ <span class="reel" style=${`--o:${10 + Number(cell.char)}`}>
3920
+ ${REEL_DIGITS.map((d) => html`<span>${d}</span>`)}
3921
+ </span>
3922
+ </span>
3923
+ `;
3924
+ return html`
3925
+ <span class="cell symbol" part="symbol" data-key=${cell.key} data-phase=${cell.phase}>${cell.char}</span>
3926
+ `;
3927
+ }
3928
+ render() {
3929
+ const section = (name) => this._cells.filter((c) => c.section === name);
3930
+ const integer = [...section(`integer`)].reverse();
3931
+ return html`
3932
+ ${this.prefix ? html`<span class="affix" part="prefix">${this.prefix}</span>` : nothing}
3933
+ <span class="number" part="number" aria-hidden="true">
3934
+ <span class="run lead">${section(`lead`).map((c) => this._renderCell(c))}</span>
3935
+ <span class="run integer" part="integer">
3936
+ ${repeat(integer, (c) => c.key, (c) => this._renderCell(c))}
3937
+ </span>
3938
+ ${section(`decimal`).map((c) => this._renderCell(c))}
3939
+ <span class="run fraction" part="fraction">
3940
+ ${repeat(section(`fraction`), (c) => c.key, (c) => this._renderCell(c))}
3941
+ </span>
3942
+ <span class="run trail">${section(`trail`).map((c) => this._renderCell(c))}</span>
3943
+ </span>
3944
+ ${this.suffix ? html`<span class="affix" part="suffix">${this.suffix}</span>` : nothing}
3945
+ `;
3946
+ }
3947
+ static {
3948
+ this.styles = css`
3949
+ :host {
3950
+ --sliding-number-spin-duration: 0.7s;
3951
+ --sliding-number-spin-easing: cubic-bezier(0.16, 1, 0.3, 1);
3952
+ --sliding-number-transform-duration: 0.5s;
3953
+ --sliding-number-transform-easing: cubic-bezier(0.16, 1, 0.3, 1);
3954
+ --sliding-number-opacity-duration: 0.35s;
3955
+ --sliding-number-digit-width: 1ch;
3956
+
3957
+ display: inline-flex;
3958
+ align-items: flex-end;
3959
+ line-height: 1;
3960
+ font-variant-numeric: tabular-nums;
3961
+ }
3962
+
3963
+ .number,
3964
+ .run {
3965
+ display: inline-flex;
3966
+ /* Every cell is exactly 1em tall, so aligning bottom edges keeps
3967
+ every glyph on the same line without relying on synthesised
3968
+ flex baselines (which break under overflow: hidden). */
3969
+ align-items: flex-end;
3970
+ white-space: nowrap;
3971
+ }
3972
+
3973
+ .affix {
3974
+ line-height: 1;
3975
+ }
3976
+
3977
+ /* Integer digits stack right-to-left so the units column (next to the
3978
+ decimal point) stays put while higher places grow outward. */
3979
+ .run.integer {
3980
+ flex-direction: row-reverse;
3981
+ }
3982
+
3983
+ .cell {
3984
+ display: block;
3985
+ height: 1em;
3986
+ line-height: 1;
3987
+ text-align: center;
3988
+ overflow: hidden;
3989
+ transition:
3990
+ width var(--sliding-number-transform-duration) var(--sliding-number-transform-easing),
3991
+ max-width var(--sliding-number-transform-duration) var(--sliding-number-transform-easing),
3992
+ opacity var(--sliding-number-opacity-duration) var(--sliding-number-transform-easing);
3993
+ }
3994
+
3995
+ .cell.digit {
3996
+ position: relative;
3997
+ width: var(--sliding-number-digit-width);
3998
+ }
3999
+
4000
+ .cell.symbol {
4001
+ max-width: 4ch;
4002
+ }
4003
+
4004
+ .cell[data-phase='enter'],
4005
+ .cell[data-phase='leave'] {
4006
+ opacity: 0;
4007
+ }
4008
+
4009
+ .cell.digit[data-phase='enter'],
4010
+ .cell.digit[data-phase='leave'] {
4011
+ width: 0;
4012
+ }
4013
+
4014
+ .cell.symbol[data-phase='enter'],
4015
+ .cell.symbol[data-phase='leave'] {
4016
+ max-width: 0;
4017
+ }
4018
+
4019
+ .reel {
4020
+ position: absolute;
4021
+ inset: 0 0 auto 0;
4022
+ display: flex;
4023
+ flex-direction: column;
4024
+ will-change: transform;
4025
+ transform: translateY(calc(-1em * var(--o, 10)));
4026
+ }
4027
+
4028
+ .reel > span {
4029
+ display: block;
4030
+ height: 1em;
4031
+ line-height: 1;
4032
+ text-align: center;
4033
+ }
4034
+
4035
+ :host([data-static]) .cell {
4036
+ transition: none;
4037
+ }
4038
+ `;
4039
+ }
4040
+ };
4041
+ __decorate([property({ type: Number })], SlidingNumberElement.prototype, "value", void 0);
4042
+ __decorate([property({ type: String })], SlidingNumberElement.prototype, "locales", void 0);
4043
+ __decorate([property({ type: Object })], SlidingNumberElement.prototype, "format", void 0);
4044
+ __decorate([property({ type: String })], SlidingNumberElement.prototype, "prefix", void 0);
4045
+ __decorate([property({ type: String })], SlidingNumberElement.prototype, "suffix", void 0);
4046
+ __decorate([property({ type: String })], SlidingNumberElement.prototype, "trend", void 0);
4047
+ __decorate([property({
4048
+ type: Boolean,
4049
+ attribute: `no-animate`
4050
+ })], SlidingNumberElement.prototype, "noAnimate", void 0);
4051
+ __decorate([property({
4052
+ type: Boolean,
4053
+ attribute: false
4054
+ })], SlidingNumberElement.prototype, "respectMotionPreference", void 0);
4055
+ __decorate([state()], SlidingNumberElement.prototype, "_cells", void 0);
4056
+ SlidingNumberElement = __decorate([safeCustomElement(`ixfx-sliding-number`)], SlidingNumberElement);
4057
+ //#endregion
3632
4058
  //#region src/tabs/tab-list-item.ts
3633
4059
  let TabListItemElement = class TabListItemElement extends LitElement {
3634
4060
  constructor(..._args) {
@@ -4275,6 +4701,390 @@ let TabPanelsElement = class TabPanelsElement extends LitElement {
4275
4701
  __decorate([queryAssignedElements()], TabPanelsElement.prototype, "_listItems", void 0);
4276
4702
  TabPanelsElement = __decorate([safeCustomElement(`ixfx-tab-panels`)], TabPanelsElement);
4277
4703
  //#endregion
4704
+ //#region src/text-shimmer/text-shimmer.ts
4705
+ let TextShimmerElement = class TextShimmerElement extends LitElement {
4706
+ constructor(..._args) {
4707
+ super(..._args);
4708
+ this.text = ``;
4709
+ this.paused = false;
4710
+ }
4711
+ render() {
4712
+ return html`<span class="shimmer" part="text"
4713
+ >${this.text === `` ? html`<slot></slot>` : this.text}</span
4714
+ >`;
4715
+ }
4716
+ static {
4717
+ this.styles = css`
4718
+ :host {
4719
+ --text-shimmer-color: var(--surface-3-text, #888);
4720
+ --text-shimmer-gradient-color: var(--surface-2-text, #fff);
4721
+ --text-shimmer-duration: 2s;
4722
+ --text-shimmer-spread: 15%;
4723
+
4724
+ display: inline-block;
4725
+ color: var(--text-shimmer-color);
4726
+ }
4727
+
4728
+ .shimmer {
4729
+ background-image: linear-gradient(
4730
+ 90deg,
4731
+ var(--text-shimmer-color) 0%,
4732
+ var(--text-shimmer-color) calc(50% - var(--text-shimmer-spread)),
4733
+ var(--text-shimmer-gradient-color) 50%,
4734
+ var(--text-shimmer-color) calc(50% + var(--text-shimmer-spread)),
4735
+ var(--text-shimmer-color) 100%
4736
+ );
4737
+ background-size: 250% 100%;
4738
+ background-repeat: no-repeat;
4739
+ -webkit-background-clip: text;
4740
+ background-clip: text;
4741
+ color: transparent;
4742
+ -webkit-text-fill-color: transparent;
4743
+ animation: ixfx-text-shimmer-sweep var(--text-shimmer-duration) linear infinite;
4744
+ }
4745
+
4746
+ /* Sweep the highlight band from the right edge to the left edge. */
4747
+ @keyframes ixfx-text-shimmer-sweep {
4748
+ from {
4749
+ background-position: 100% center;
4750
+ }
4751
+ to {
4752
+ background-position: 0% center;
4753
+ }
4754
+ }
4755
+
4756
+ :host([paused]) .shimmer {
4757
+ animation: none;
4758
+ background-image: none;
4759
+ color: var(--text-shimmer-color);
4760
+ -webkit-text-fill-color: var(--text-shimmer-color);
4761
+ }
4762
+
4763
+ @media (prefers-reduced-motion: reduce) {
4764
+ .shimmer {
4765
+ animation: none;
4766
+ background-image: none;
4767
+ color: var(--text-shimmer-color);
4768
+ -webkit-text-fill-color: var(--text-shimmer-color);
4769
+ }
4770
+ }
4771
+ `;
4772
+ }
4773
+ };
4774
+ __decorate([property({ type: String })], TextShimmerElement.prototype, "text", void 0);
4775
+ __decorate([property({
4776
+ type: Boolean,
4777
+ reflect: true
4778
+ })], TextShimmerElement.prototype, "paused", void 0);
4779
+ TextShimmerElement = __decorate([safeCustomElement(`ixfx-text-shimmer`)], TextShimmerElement);
4780
+ //#endregion
4781
+ //#region src/toolbar/toolbar-group.ts
4782
+ let ToolbarGroupElement = class ToolbarGroupElement extends LitElement {
4783
+ constructor(..._args) {
4784
+ super(..._args);
4785
+ this.label = ``;
4786
+ this.grow = false;
4787
+ }
4788
+ static {
4789
+ this.styles = [themeFallbacks, css`
4790
+ :host {
4791
+ display: flex;
4792
+ flex-direction: column;
4793
+ align-items: var(--toolbar-group-align-items, center);
4794
+ justify-content: var(--toolbar-group-justify-content, flex-start);
4795
+ gap: var(--toolbar-gap, var(--space-s));
4796
+ padding: var(--space-xs);
4797
+ border: 1px solid var(--border-subtle, var(--border));
4798
+ border-radius: var(--radius-s);
4799
+ background: var(--surface-3);
4800
+ min-width: 0;
4801
+ }
4802
+ :host(:not([label])) {
4803
+ border: none;
4804
+ background: transparent;
4805
+ padding: 0;
4806
+ }
4807
+ .label-row {
4808
+ display: none;
4809
+ font-size: var(--text-s, 12px);
4810
+ color: var(--surface-muted-text);
4811
+ padding-inline: var(--space-xs);
4812
+ white-space: nowrap;
4813
+ border-bottom: 1px solid var(--border-subtle);
4814
+ margin-bottom: var(--space-xs);
4815
+ }
4816
+ :host([label][show-label]) .label-row { display: block; }
4817
+ :host(:not([label])) .label-row { display: none; }
4818
+ :host([grow]) { flex: 1 1 auto; min-width: 0; }
4819
+ :host([hidden]) { display: none !important; }
4820
+ .components { display: flex; }
4821
+ ::slotted(*) { flex: 0 0 auto; }
4822
+ ::slotted([grow]) { flex: 1 1 auto; }
4823
+ `];
4824
+ }
4825
+ render() {
4826
+ return html`
4827
+ <div class="label-row">${this.label}</div>
4828
+ <div class="components">
4829
+ <slot></slot>
4830
+ </div>
4831
+ `;
4832
+ }
4833
+ };
4834
+ __decorate([property({ type: String })], ToolbarGroupElement.prototype, "label", void 0);
4835
+ __decorate([property({
4836
+ type: Boolean,
4837
+ reflect: true
4838
+ })], ToolbarGroupElement.prototype, "grow", void 0);
4839
+ ToolbarGroupElement = __decorate([safeCustomElement(`ixfx-toolbar-group`)], ToolbarGroupElement);
4840
+ //#endregion
4841
+ //#region src/toolbar/toolbar.ts
4842
+ var _ToolbarElement;
4843
+ let ToolbarElement = class ToolbarElement extends LitElement {
4844
+ static {
4845
+ _ToolbarElement = this;
4846
+ }
4847
+ constructor(..._args) {
4848
+ super(..._args);
4849
+ this.orientation = `horizontal`;
4850
+ this.layout = `one-line`;
4851
+ this.verticalWriting = `auto`;
4852
+ this.showGroupLabels = false;
4853
+ this.invisibleGroups = false;
4854
+ this._overflowCount = 0;
4855
+ this._ro = null;
4856
+ this._anchor = `--toolbar-${_ToolbarElement._cnt++}`;
4857
+ this._sizes = /* @__PURE__ */ new WeakMap();
4858
+ this._measureQueued = false;
4859
+ }
4860
+ static {
4861
+ this._cnt = 0;
4862
+ }
4863
+ static {
4864
+ this.styles = [
4865
+ themeFallbacks,
4866
+ popupSurfaceStyles,
4867
+ css`
4868
+ :host {
4869
+ --toolbar-gap: var(--space-s);
4870
+ --toolbar-group-gap: var(--space-m);
4871
+ display: block;
4872
+ container-type: inline-size;
4873
+ }
4874
+ :host([orientation="vertical-left"]),
4875
+ :host([orientation="vertical-right"]) {
4876
+ container-type: normal;
4877
+ width: max-content;
4878
+ }
4879
+ :host([orientation="vertical-left"]),
4880
+ :host([orientation="vertical-right"]) { height: 100%; }
4881
+ :host([orientation="vertical-left"]) .inner,
4882
+ :host([orientation="vertical-right"]) .inner { height: 100%; box-sizing: border-box; width: max-content; }
4883
+ .inner {
4884
+ display: flex;
4885
+ gap: var(--toolbar-gap);
4886
+ background: var(--toolbar-bg, var(--surface-2));
4887
+ padding: var(--toolbar-padding, var(--space-s));
4888
+ border: var(--toolbar-border, var(--border-subtle));
4889
+ border-radius: var(--radius-s);
4890
+ align-items: center;
4891
+ }
4892
+ :host([orientation="horizontal"]) .inner { flex-direction: row; justify-content: flex-start; }
4893
+ :host([orientation="vertical-left"]) .inner { flex-direction: column-reverse; align-items: stretch; }
4894
+ :host([orientation="vertical-right"]) .inner { flex-direction: column; align-items: stretch; }
4895
+ :host([layout="wrap"]) .inner { flex-wrap: wrap; }
4896
+ :host([layout="one-line"]) .inner { flex-wrap: nowrap; overflow: hidden; }
4897
+ :host([orientation="vertical-left"][vertical-writing="auto"]) ::slotted(*) { writing-mode: sideways-lr; }
4898
+ :host([orientation="vertical-right"][vertical-writing="auto"]) ::slotted(*) { writing-mode: vertical-lr; }
4899
+ :host([vertical-writing="up"]) ::slotted(*) { writing-mode: vertical-rl; text-orientation: upright; }
4900
+ :host([vertical-writing="down"]) ::slotted(*) { writing-mode: vertical-lr; }
4901
+ :host([vertical-writing="none"]) ::slotted(*) { writing-mode: horizontal-tb; }
4902
+ ::slotted(*) { flex: 0 0 auto; }
4903
+ ::slotted([grow]), ::slotted(ixfx-toolbar-group[grow]) { flex: 1 1 auto; }
4904
+ ::slotted([hidden]) { display: none !important; }
4905
+ :host([invisible-groups]) ::slotted(ixfx-toolbar-group) { --toolbar-group-border: none; }
4906
+ .overflow-btn {
4907
+ anchor-name: var(--anchor-name);
4908
+ flex-shrink: 0;
4909
+ background: var(--surface-3);
4910
+ border: var(--border);
4911
+ border-radius: var(--radius-s);
4912
+ padding: var(--space-xs) var(--space-s);
4913
+ cursor: pointer;
4914
+ display: none;
4915
+ }
4916
+ .overflow-btn[visible] { display: inline-flex; }
4917
+ .overflow-popover {
4918
+ position: fixed;
4919
+ top: anchor(bottom);
4920
+ left: anchor(right);
4921
+ position-anchor: var(--anchor-name);
4922
+ position-try-fallbacks: flip-block, flip-inline, flip-block flip-inline;
4923
+ margin: 8px;
4924
+ max-height: min(60vh, 400px);
4925
+ max-width: min(90vw, 320px);
4926
+ overflow: auto;
4927
+ overscroll-behavior: contain;
4928
+ z-index: 100;
4929
+ padding: var(--space-s);
4930
+ flex-direction: column;
4931
+ gap: var(--space-s);
4932
+ }
4933
+ .overflow-popover:popover-open { display: flex; }
4934
+ .overflow-popover ::slotted(*) { writing-mode: horizontal-tb; text-orientation: mixed; }
4935
+ `
4936
+ ];
4937
+ }
4938
+ connectedCallback() {
4939
+ super.connectedCallback();
4940
+ this.style.setProperty(`--anchor-name`, this._anchor);
4941
+ }
4942
+ firstUpdated() {
4943
+ this._slot.addEventListener(`slotchange`, () => this._scheduleMeasure());
4944
+ this._ro = new ResizeObserver(() => this._scheduleMeasure());
4945
+ this._ro.observe(this._inner);
4946
+ this._scheduleMeasure();
4947
+ this._updateGroupLabels();
4948
+ }
4949
+ updated(changed) {
4950
+ if (changed.has(`showGroupLabels`)) this._updateGroupLabels();
4951
+ }
4952
+ _updateGroupLabels() {
4953
+ for (const child of Array.from(this.children)) if (child.tagName === `IXFX-TOOLBAR-GROUP`) {
4954
+ if (this.showGroupLabels) child.setAttribute(`show-label`, ``);
4955
+ else child.removeAttribute(`show-label`);
4956
+ }
4957
+ }
4958
+ disconnectedCallback() {
4959
+ super.disconnectedCallback();
4960
+ this._ro?.disconnect();
4961
+ }
4962
+ /** Coalesce measure passes into one per frame; prevents slotchange feedback loops. */
4963
+ _scheduleMeasure() {
4964
+ if (this._measureQueued) return;
4965
+ this._measureQueued = true;
4966
+ requestAnimationFrame(() => {
4967
+ this._measureQueued = false;
4968
+ this._measure();
4969
+ });
4970
+ }
4971
+ _measure() {
4972
+ const children = Array.from(this.children);
4973
+ const isGrow = (el) => el.hasAttribute(`grow`) || el.matches(`[grow]`);
4974
+ const overflowable = children.filter((el) => !isGrow(el));
4975
+ const isHoriz = this.orientation === `horizontal`;
4976
+ if (this.layout !== `one-line`) {
4977
+ let mutated = false;
4978
+ for (const el of children) {
4979
+ if (el.getAttribute(`slot`) === `overflow`) {
4980
+ el.removeAttribute(`slot`);
4981
+ mutated = true;
4982
+ }
4983
+ if (el.hasAttribute(`hidden`)) {
4984
+ el.removeAttribute(`hidden`);
4985
+ mutated = true;
4986
+ }
4987
+ }
4988
+ if (this._overflowCount !== 0) {
4989
+ this._overflowCount = 0;
4990
+ mutated = true;
4991
+ }
4992
+ if (mutated) this.requestUpdate();
4993
+ return;
4994
+ }
4995
+ if (!this._inner) return;
4996
+ const cs = getComputedStyle(this._inner);
4997
+ const gap = (isHoriz ? Number.parseFloat(cs.columnGap) : Number.parseFloat(cs.rowGap)) || 0;
4998
+ const available = isHoriz ? this._inner.clientWidth : this._inner.clientHeight;
4999
+ const btnSize = 36;
5000
+ const inMain = overflowable.filter((el) => el.getAttribute(`slot`) !== `overflow`);
5001
+ const inOverflow = overflowable.filter((el) => el.getAttribute(`slot`) === `overflow`);
5002
+ let cum = 0;
5003
+ inMain.forEach((el, i) => {
5004
+ const s = isHoriz ? el.offsetWidth : el.offsetHeight;
5005
+ if (s > 0) this._sizes.set(el, s);
5006
+ cum += (i ? gap : 0) + (this._sizes.get(el) ?? s);
5007
+ });
5008
+ const btnAllowance = inOverflow.length > 0 ? gap + btnSize : 0;
5009
+ let mutated = false;
5010
+ while (inMain.length > 0 && cum + btnAllowance > available) {
5011
+ const last = inMain[inMain.length - 1];
5012
+ const s = this._sizes.get(last) ?? 0;
5013
+ last.setAttribute(`slot`, `overflow`);
5014
+ inMain.pop();
5015
+ inOverflow.unshift(last);
5016
+ cum -= (inMain.length ? gap : 0) + s;
5017
+ mutated = true;
5018
+ }
5019
+ while (inOverflow.length > 0) {
5020
+ const first = inOverflow[0];
5021
+ const s = this._sizes.get(first);
5022
+ if (s === void 0) break;
5023
+ const addGap = inMain.length ? gap : 0;
5024
+ const nextBtnAllowance = inOverflow.length > 1 ? gap + btnSize : 0;
5025
+ if (cum + addGap + s + nextBtnAllowance > available) break;
5026
+ first.removeAttribute(`slot`);
5027
+ inOverflow.shift();
5028
+ inMain.push(first);
5029
+ cum += addGap + s;
5030
+ mutated = true;
5031
+ }
5032
+ const newCount = inOverflow.length;
5033
+ if (newCount !== this._overflowCount) {
5034
+ this._overflowCount = newCount;
5035
+ mutated = true;
5036
+ }
5037
+ if (mutated) this.requestUpdate();
5038
+ }
5039
+ _toggleOverflow() {
5040
+ try {
5041
+ this._popover.togglePopover();
5042
+ } catch {
5043
+ this._popover.showPopover();
5044
+ }
5045
+ }
5046
+ render() {
5047
+ const hasOverflow = this._overflowCount > 0;
5048
+ return html`
5049
+ <div class="inner" role="toolbar" aria-orientation=${this.orientation}>
5050
+ <slot></slot>
5051
+ <button class="overflow-btn" ?visible=${hasOverflow} @click=${this._toggleOverflow} aria-label="More" aria-haspopup="true" aria-expanded=${this._popover?.matches(`:popover-open`) ?? false}>⋯</button>
5052
+ </div>
5053
+ <div class="overflow-popover popup-surface" popover="auto" @click=${(e) => e.stopPropagation()}>
5054
+ <slot name="overflow"></slot>
5055
+ </div>
5056
+ `;
5057
+ }
5058
+ };
5059
+ __decorate([property({
5060
+ type: String,
5061
+ reflect: true
5062
+ })], ToolbarElement.prototype, "orientation", void 0);
5063
+ __decorate([property({
5064
+ type: String,
5065
+ reflect: true
5066
+ })], ToolbarElement.prototype, "layout", void 0);
5067
+ __decorate([property({
5068
+ type: String,
5069
+ attribute: `vertical-writing`,
5070
+ reflect: true
5071
+ })], ToolbarElement.prototype, "verticalWriting", void 0);
5072
+ __decorate([property({
5073
+ type: Boolean,
5074
+ attribute: `show-group-labels`,
5075
+ reflect: true
5076
+ })], ToolbarElement.prototype, "showGroupLabels", void 0);
5077
+ __decorate([property({
5078
+ type: Boolean,
5079
+ attribute: `invisible-groups`,
5080
+ reflect: true
5081
+ })], ToolbarElement.prototype, "invisibleGroups", void 0);
5082
+ __decorate([state()], ToolbarElement.prototype, "_overflowCount", void 0);
5083
+ __decorate([query(`.inner`)], ToolbarElement.prototype, "_inner", void 0);
5084
+ __decorate([query(`.overflow-popover`)], ToolbarElement.prototype, "_popover", void 0);
5085
+ __decorate([query(`slot`)], ToolbarElement.prototype, "_slot", void 0);
5086
+ ToolbarElement = _ToolbarElement = __decorate([safeCustomElement(`ixfx-toolbar`)], ToolbarElement);
5087
+ //#endregion
4278
5088
  //#region src/util/checkbox.ts
4279
5089
  function isCheckboxLike(el) {
4280
5090
  if (!(el instanceof HTMLElement)) return false;
@@ -4332,6 +5142,6 @@ function init() {
4332
5142
  console.log(`Init`);
4333
5143
  }
4334
5144
  //#endregion
4335
- export { AcTextElement, AcTokenElement, ButtonElement, Checkbox, ColourPicker, ColourPickerPopup, CrumbNavigationElement, CrumbPathController, CrumbPathElement, DataController, DataDisplayComponent, DataGridElement, EditableLabel, EditableNumber, FormElement, FormGroupElement, FormPartElement, GroupedItemListerElement, ICON_CARET_RIGHT, ICON_CHECK, ICON_CHEVRON_DOWN, ICON_CLOSE, IncrSearchTreeController as IncrSearchMillerController, IncrSearchTreeController, IxfxHexEditorElement, IxfxIconElement, IxfxTimelineElement, LabelledRadialInput, LabelledRangeInput, LedElement, menu_exports as Menu, MillerBaseElement, MillerListElement, MillerTreeController, NarrowedTextElement, NotificationManager, NotificationPillElement, PanelElement, PanelGroupElement, PlotDataSeries, PlotHistogram, PlotMultiAxis, PlotSingleAxis, PlotXyAxis, PolarPad, RadialInputElement, RadioGroup, RangeElement, RangeInput, RangeMultiElement, RatingElement, SelectHorizElement, SliderInputElement, SnackbarElement, SnapContainer, SplitButton, SplitLayoutElement, SwipeElement, TabController, TabListElement, TabListItemElement, TabPanelElement, TabPanelsElement, TimelineController, TimelineTrackTabElement, TooltipElement, TransitoryLabelElement, TreeBaseElement, TreeController, TreeDataModel, TreeListElement, VerticalListElement, XyPad, applyAgeModification, applyHighlights, attachTimelineInteractions, buildHighlightTargets, clearHighlights, collectDataResult, computeColour, createAcCompletionProvider, createElementIncrSearch, createFuzzySearch, createIncrSearch, createPillRenderer, createTreeListAdapter, createVerticalListAdapter, getIcon, hasIcon, iconBus, init, monitorIndeterminate, parseColourScaleAttr, readBaseColour, registerIcon, resolveCssVars, resolveGrid, svgToDataUri, timelineStyles };
5145
+ export { AcTextElement, AcTokenElement, ButtonElement, Checkbox, ColourPicker, ColourPickerPopup, CrumbNavigationElement, CrumbPathController, CrumbPathElement, DataController, DataDisplayComponent, DataGridElement, EditableLabel, EditableNumber, FormElement, FormGroupElement, FormPartElement, GroupedItemListerElement, ICON_CARET_RIGHT, ICON_CHECK, ICON_CHEVRON_DOWN, ICON_CLOSE, IncrSearchTreeController as IncrSearchMillerController, IncrSearchTreeController, IxfxHexEditorElement, IxfxIconElement, IxfxTimelineElement, LabelledRadialInput, LabelledRangeInput, LedElement, menu_exports as Menu, MillerBaseElement, MillerListElement, MillerTreeController, NarrowedTextElement, NotificationManager, NotificationPillElement, PanelElement, PanelGroupElement, PlotDataSeries, PlotHistogram, PlotMultiAxis, PlotSingleAxis, PlotXyAxis, PolarPad, RadialInputElement, RadioGroup, RangeElement, RangeInput, RangeMultiElement, RatingElement, SelectHorizElement, SliderInputElement, SlidingNumberElement, SnackbarElement, SnapContainer, SplitButton, SplitLayoutElement, SwipeElement, TabController, TabListElement, TabListItemElement, TabPanelElement, TabPanelsElement, TextShimmerElement, TimelineController, TimelineTrackTabElement, ToolbarElement, ToolbarGroupElement, TooltipElement, TransitoryLabelElement, TreeBaseElement, TreeController, TreeDataModel, TreeListElement, VerticalListElement, XyPad, applyAgeModification, applyHighlights, attachTimelineInteractions, buildHighlightTargets, clearHighlights, collectDataResult, computeColour, createAcCompletionProvider, createElementIncrSearch, createFuzzySearch, createIncrSearch, createPillRenderer, createTreeListAdapter, createVerticalListAdapter, getIcon, hasIcon, iconBus, init, monitorIndeterminate, parseColourScaleAttr, readBaseColour, registerIcon, resolveCssVars, resolveGrid, svgToDataUri, timelineStyles };
4336
5146
 
4337
5147
  //# sourceMappingURL=index.js.map