@arvea/components 0.0.1 → 0.0.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.
package/dist/index.cjs CHANGED
@@ -3418,6 +3418,7 @@ exports.ArveaBadge = class ArveaBadge extends lit.LitElement {
3418
3418
  this.textColor = "";
3419
3419
  this.icon = "";
3420
3420
  this.noBg = false;
3421
+ this.hideIcon = false;
3421
3422
  this.selected = true;
3422
3423
  }
3423
3424
  render() {
@@ -3426,7 +3427,7 @@ exports.ArveaBadge = class ArveaBadge extends lit.LitElement {
3426
3427
  ...this.color ? { background: this.color } : {},
3427
3428
  ...this.textColor ? { color: this.textColor } : {}
3428
3429
  });
3429
- const showIcon = this.icon || isStatus;
3430
+ const showIcon = !this.hideIcon && (this.icon || isStatus);
3430
3431
  const iconTpl = showIcon ? this.icon ? lit.html`<arvea-icon part="icon" class="icon" name=${this.icon} size="sm"></arvea-icon>` : lit.html`<span part="icon" class="icon">${unsafeSvg_js.unsafeSVG(BADGE_ICONS[this.variant])}</span>` : lit.nothing;
3431
3432
  return lit.html`
3432
3433
  <span
@@ -3468,6 +3469,9 @@ __decorateClass([
3468
3469
  __decorateClass([
3469
3470
  decorators_js.property({ type: Boolean, reflect: true, attribute: "no-bg" })
3470
3471
  ], exports.ArveaBadge.prototype, "noBg", 2);
3472
+ __decorateClass([
3473
+ decorators_js.property({ type: Boolean, reflect: true, attribute: "hide-icon" })
3474
+ ], exports.ArveaBadge.prototype, "hideIcon", 2);
3471
3475
  __decorateClass([
3472
3476
  decorators_js.property({ type: Boolean, reflect: true })
3473
3477
  ], exports.ArveaBadge.prototype, "selected", 2);
@@ -4034,10 +4038,10 @@ exports.ArveaSlider = class ArveaSlider extends lit.LitElement {
4034
4038
  };
4035
4039
  }
4036
4040
  get _percentage() {
4037
- const range = this.max - this.min;
4038
- if (range <= 0) return 0;
4041
+ const range2 = this.max - this.min;
4042
+ if (range2 <= 0) return 0;
4039
4043
  const clamped = Math.max(this.min, Math.min(this.value, this.max));
4040
- return (clamped - this.min) / range * 100;
4044
+ return (clamped - this.min) / range2 * 100;
4041
4045
  }
4042
4046
  _ticks() {
4043
4047
  if (!this.tickStep || this.tickStep <= 0) return [];
@@ -4046,9 +4050,9 @@ exports.ArveaSlider = class ArveaSlider extends lit.LitElement {
4046
4050
  return out;
4047
4051
  }
4048
4052
  _tickPercent(v) {
4049
- const range = this.max - this.min;
4050
- if (range <= 0) return 0;
4051
- return (v - this.min) / range * 100;
4053
+ const range2 = this.max - this.min;
4054
+ if (range2 <= 0) return 0;
4055
+ return (v - this.min) / range2 * 100;
4052
4056
  }
4053
4057
  _formatValue() {
4054
4058
  return `${this.valuePrefix}${this.value}${this.valueSuffix}`;
@@ -9406,7 +9410,7 @@ var arveaDialogStyles = [
9406
9410
  box-shadow: var(--dialog-shadow);
9407
9411
  padding: var(--dialog-padding);
9408
9412
  max-height: 90vh;
9409
- overflow-y: auto;
9413
+ overflow: visible;
9410
9414
  transform: translateY(-8px) scale(0.98);
9411
9415
  opacity: 0;
9412
9416
  transition: opacity 0.2s ease, transform 0.2s ease;
@@ -12629,8 +12633,8 @@ exports.ArveaStepper = class ArveaStepper extends lit.LitElement {
12629
12633
  })
12630
12634
  );
12631
12635
  }
12632
- _renderCircle(i, state20) {
12633
- if (state20 === "complete") {
12636
+ _renderCircle(i, state21) {
12637
+ if (state21 === "complete") {
12634
12638
  return lit.html`<span part="circle" class="circle">
12635
12639
  <svg class="check" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="2">
12636
12640
  <path d="m3.5 8.5 3 3 6-7" stroke-linecap="round" stroke-linejoin="round"/>
@@ -12643,18 +12647,18 @@ exports.ArveaStepper = class ArveaStepper extends lit.LitElement {
12643
12647
  return lit.html`
12644
12648
  <ol part="base" aria-label="Progress">
12645
12649
  ${this.steps.map((step, i) => {
12646
- const state20 = this._stateOf(i);
12650
+ const state21 = this._stateOf(i);
12647
12651
  const isLast = i === this.steps.length - 1;
12648
12652
  const stepEl = lit.html`<button
12649
12653
  part="step"
12650
12654
  class="step"
12651
12655
  type="button"
12652
- data-state=${state20}
12653
- aria-current=${state20 === "active" ? "step" : lit.nothing}
12654
- ?disabled=${!this.clickable || state20 === "upcoming"}
12656
+ data-state=${state21}
12657
+ aria-current=${state21 === "active" ? "step" : lit.nothing}
12658
+ ?disabled=${!this.clickable || state21 === "upcoming"}
12655
12659
  @click=${() => this._onStepClick(i)}
12656
12660
  >
12657
- ${this._renderCircle(i, state20)}
12661
+ ${this._renderCircle(i, state21)}
12658
12662
  <span part="meta" class="meta">
12659
12663
  <span part="label" class="label">${step.label}</span>
12660
12664
  ${step.description ? lit.html`<span part="description" class="description">${step.description}</span>` : lit.nothing}
@@ -12662,7 +12666,7 @@ exports.ArveaStepper = class ArveaStepper extends lit.LitElement {
12662
12666
  </button>`;
12663
12667
  const connector = isLast ? lit.nothing : lit.html`<span
12664
12668
  part="connector"
12665
- class="connector ${state20 === "complete" ? "complete" : ""}"
12669
+ class="connector ${state21 === "complete" ? "complete" : ""}"
12666
12670
  aria-hidden="true"
12667
12671
  ></span>`;
12668
12672
  return lit.html`<li
@@ -13545,11 +13549,24 @@ exports.ArveaDataTable = class ArveaDataTable extends lit.LitElement {
13545
13549
  }
13546
13550
  _renderCell(col, row, index) {
13547
13551
  if (col.image) return this._renderImageCell(row[col.key]);
13552
+ if (col.badge) return this._renderBadgeCell(col.badge(row, index));
13548
13553
  if (col.actions) return this._renderActionsCell(col.actions(row, index), row, index);
13549
13554
  if (col.render) return col.render(row, index);
13550
13555
  const v = row[col.key];
13551
13556
  return v == null ? "" : String(v);
13552
13557
  }
13558
+ _renderBadgeCell(badge2) {
13559
+ if (!badge2) return lit.nothing;
13560
+ return lit.html`<arvea-badge
13561
+ variant=${badge2.variant ?? lit.nothing}
13562
+ label=${badge2.label ?? lit.nothing}
13563
+ color=${badge2.color ?? lit.nothing}
13564
+ text-color=${badge2.textColor ?? lit.nothing}
13565
+ icon=${badge2.icon ?? lit.nothing}
13566
+ ?no-bg=${badge2.noBg ?? false}
13567
+ ?hide-icon=${badge2.hideIcon ?? false}
13568
+ ></arvea-badge>`;
13569
+ }
13553
13570
  _renderImageCell(src) {
13554
13571
  return src ? lit.html`<img class="cell-image" src=${src} alt="" loading="lazy" />` : lit.html`<span class="cell-image cell-image--empty" aria-hidden="true">
13555
13572
  <arvea-icon name="file" size="sm" outline></arvea-icon>
@@ -17800,6 +17817,364 @@ __decorateClass([
17800
17817
  exports.ArveaDatePicker = __decorateClass([
17801
17818
  decorators_js.customElement("arvea-date-picker")
17802
17819
  ], exports.ArveaDatePicker);
17820
+ var arveaTimeSelectStyles = [
17821
+ tokenStyles,
17822
+ lit.css`
17823
+ :host {
17824
+ display: block;
17825
+ font-family: inherit;
17826
+ width: 100%;
17827
+ }
17828
+
17829
+ .field {
17830
+ display: flex;
17831
+ flex-direction: column;
17832
+ gap: 6px;
17833
+ }
17834
+
17835
+ .label {
17836
+ font-size: var(--input-label-size);
17837
+ font-weight: var(--input-label-weight);
17838
+ color: var(--input-label-color);
17839
+ }
17840
+
17841
+ .segments {
17842
+ display: flex;
17843
+ align-items: center;
17844
+ gap: 4px;
17845
+ }
17846
+
17847
+ .sep {
17848
+ font-weight: 600;
17849
+ color: var(--colors-slate-400, #94a3b8);
17850
+ }
17851
+
17852
+ .segment {
17853
+ position: relative;
17854
+ flex: 1;
17855
+ min-width: 0;
17856
+ }
17857
+
17858
+ .segment-trigger {
17859
+ width: 100%;
17860
+ box-sizing: border-box;
17861
+ display: flex;
17862
+ align-items: center;
17863
+ justify-content: space-between;
17864
+ gap: 6px;
17865
+ height: var(--input-height, 38px);
17866
+ padding: 0 10px;
17867
+ font: inherit;
17868
+ color: inherit;
17869
+ background: var(--input-bg, #fff);
17870
+ border: 1px solid var(--input-border, #e2e8f0);
17871
+ border-radius: var(--input-radius, 6px);
17872
+ cursor: pointer;
17873
+ }
17874
+ .segment-trigger:hover:not(:disabled) {
17875
+ border-color: var(--input-border-hover, #cbd5e1);
17876
+ }
17877
+ .segment-trigger:focus-visible {
17878
+ outline: none;
17879
+ border-color: var(--input-border-focus, #3b82f6);
17880
+ box-shadow: var(--input-shadow-focus);
17881
+ }
17882
+ :host([invalid]) .segment-trigger {
17883
+ border-color: var(--select-border-invalid, #ef4444);
17884
+ }
17885
+ .segment-trigger:disabled {
17886
+ cursor: not-allowed;
17887
+ background: var(--input-bg-disabled, #f1f5f9);
17888
+ }
17889
+
17890
+ .chevron {
17891
+ flex-shrink: 0;
17892
+ color: var(--colors-slate-500, #64748b);
17893
+ }
17894
+
17895
+ .segment-popup {
17896
+ position: absolute;
17897
+ top: calc(100% + 4px);
17898
+ left: 0;
17899
+ right: 0;
17900
+ z-index: var(--popover-z, 9999);
17901
+ background: #fff;
17902
+ border: 1px solid var(--colors-slate-200, #e2e8f0);
17903
+ border-radius: 10px;
17904
+ box-shadow: 0 12px 32px rgba(15, 23, 42, 0.18);
17905
+ padding: 6px;
17906
+ max-height: 220px;
17907
+ overflow-y: auto;
17908
+ display: flex;
17909
+ flex-direction: column;
17910
+ }
17911
+ .segment-popup.flip-up {
17912
+ top: auto;
17913
+ bottom: calc(100% + 4px);
17914
+ }
17915
+
17916
+ .option {
17917
+ display: block;
17918
+ width: 100%;
17919
+ box-sizing: border-box;
17920
+ flex-shrink: 0;
17921
+ height: 32px;
17922
+ border: 0;
17923
+ background: transparent;
17924
+ border-radius: var(--datepicker-cell-radius, 6px);
17925
+ font: inherit;
17926
+ text-align: center;
17927
+ cursor: pointer;
17928
+ color: var(--colors-slate-800, #1e293b);
17929
+ }
17930
+ .option:hover:not(:disabled) {
17931
+ background: var(--colors-slate-100, #f1f5f9);
17932
+ color: var(--colors-slate-900, #0f172a);
17933
+ }
17934
+ .option.selected {
17935
+ background: var(
17936
+ --datepicker-selected-bg,
17937
+ var(--colors-arvea-600, #217b80)
17938
+ );
17939
+ color: #fff;
17940
+ }
17941
+ .option:disabled {
17942
+ opacity: 0.4;
17943
+ cursor: not-allowed;
17944
+ }
17945
+
17946
+ .hint {
17947
+ font-size: var(--input-hint-size);
17948
+ color: var(--input-hint-color);
17949
+ }
17950
+ :host([invalid]) .hint {
17951
+ color: var(--input-hint-color-invalid);
17952
+ }
17953
+ `
17954
+ ];
17955
+
17956
+ // src/components/arvea-time-select/arvea-time-select.ts
17957
+ var pad = (n) => String(n).padStart(2, "0");
17958
+ var parseTime = (value) => {
17959
+ if (!value) return null;
17960
+ const match = /^(\d{2}):(\d{2})(?::(\d{2}))?$/.exec(value);
17961
+ if (!match) return null;
17962
+ const h = Number(match[1]);
17963
+ const m = Number(match[2]);
17964
+ const s = match[3] !== void 0 ? Number(match[3]) : 0;
17965
+ if (h > 23 || m > 59 || s > 59) return null;
17966
+ return { h, m, s };
17967
+ };
17968
+ var formatTime = (parts, showSeconds) => {
17969
+ const out = [pad(parts.h), pad(parts.m)];
17970
+ if (showSeconds) out.push(pad(parts.s));
17971
+ return out.join(":");
17972
+ };
17973
+ var normalizeBound = (value) => {
17974
+ const parts = parseTime(value);
17975
+ return parts ? formatTime(parts, true) : value;
17976
+ };
17977
+ var range = (max, step) => {
17978
+ const out = [];
17979
+ for (let i = 0; i <= max; i += step > 0 ? step : 1) out.push(i);
17980
+ return out;
17981
+ };
17982
+ var SEGMENT_LABEL = { h: "Hour", m: "Minute", s: "Second" };
17983
+ exports.ArveaTimeSelect = class ArveaTimeSelect extends lit.LitElement {
17984
+ constructor() {
17985
+ super(...arguments);
17986
+ this.label = "";
17987
+ this.hideLabel = false;
17988
+ this.value = "";
17989
+ this.showSeconds = false;
17990
+ this.hourStep = 1;
17991
+ this.minuteStep = 1;
17992
+ this.secondStep = 1;
17993
+ this.disabled = false;
17994
+ this.required = false;
17995
+ this.invalid = false;
17996
+ this.validationHint = "";
17997
+ this._openSegment = null;
17998
+ this._flipUp = false;
17999
+ this._onDocPointer = (e) => {
18000
+ if (!this._openSegment) return;
18001
+ const path = e.composedPath();
18002
+ if (path.includes(this)) return;
18003
+ this._openSegment = null;
18004
+ };
18005
+ }
18006
+ connectedCallback() {
18007
+ super.connectedCallback();
18008
+ document.addEventListener("pointerdown", this._onDocPointer);
18009
+ }
18010
+ disconnectedCallback() {
18011
+ super.disconnectedCallback();
18012
+ document.removeEventListener("pointerdown", this._onDocPointer);
18013
+ }
18014
+ _toggle(segment) {
18015
+ if (this.disabled) return;
18016
+ this._openSegment = this._openSegment === segment ? null : segment;
18017
+ if (this._openSegment) queueMicrotask(() => this._positionAndScroll());
18018
+ }
18019
+ _positionAndScroll() {
18020
+ const popup = this.shadowRoot?.querySelector(".segment-popup");
18021
+ const trigger = popup?.parentElement?.querySelector(".segment-trigger");
18022
+ if (trigger && popup) {
18023
+ const rect = trigger.getBoundingClientRect();
18024
+ const popupHeight = popup.offsetHeight || 220;
18025
+ const spaceBelow = window.innerHeight - rect.bottom;
18026
+ this._flipUp = spaceBelow < popupHeight + 12 && rect.top > popupHeight + 12;
18027
+ }
18028
+ popup?.querySelector(".option.selected")?.scrollIntoView({ block: "center" });
18029
+ }
18030
+ // Falls back to midnight for whichever segments haven't been picked yet, so
18031
+ // every segment always has concrete "other two segments" to validate against.
18032
+ _current() {
18033
+ return parseTime(this.value) ?? { h: 0, m: 0, s: 0 };
18034
+ }
18035
+ _isDisabled(parts) {
18036
+ const key = formatTime(parts, true);
18037
+ if (this.min && key < normalizeBound(this.min)) return true;
18038
+ if (this.max && key > normalizeBound(this.max)) return true;
18039
+ return false;
18040
+ }
18041
+ _pick(segment, value) {
18042
+ const current = this._current();
18043
+ const next = { ...current, [segment]: value };
18044
+ if (this._isDisabled(next)) return;
18045
+ this.value = formatTime(next, this.showSeconds);
18046
+ this._openSegment = null;
18047
+ this._emit();
18048
+ }
18049
+ _emit() {
18050
+ this.dispatchEvent(new Event("input", { bubbles: true, composed: true }));
18051
+ this.dispatchEvent(new Event("change", { bubbles: true, composed: true }));
18052
+ this.dispatchEvent(
18053
+ new CustomEvent("arvea-time-change", {
18054
+ detail: { value: this.value },
18055
+ bubbles: true,
18056
+ composed: true
18057
+ })
18058
+ );
18059
+ }
18060
+ _renderSegment(segment) {
18061
+ const label = SEGMENT_LABEL[segment];
18062
+ const max = segment === "h" ? 23 : 59;
18063
+ const step = segment === "h" ? this.hourStep : segment === "m" ? this.minuteStep : this.secondStep;
18064
+ const parts = parseTime(this.value);
18065
+ const current = this._current();
18066
+ const isOpen = this._openSegment === segment;
18067
+ return lit.html`
18068
+ <div class="segment">
18069
+ <button
18070
+ type="button"
18071
+ class="segment-trigger"
18072
+ aria-label=${label}
18073
+ aria-haspopup="listbox"
18074
+ aria-expanded=${isOpen ? "true" : "false"}
18075
+ ?disabled=${this.disabled}
18076
+ @click=${() => this._toggle(segment)}
18077
+ >
18078
+ <span>${parts ? pad(parts[segment]) : "--"}</span>
18079
+ <svg class="chevron" width="10" height="10" viewBox="0 0 10 10" fill="none" aria-hidden="true">
18080
+ <path
18081
+ d="M2 3.5l3 3 3-3"
18082
+ stroke="currentColor"
18083
+ stroke-width="1.3"
18084
+ stroke-linecap="round"
18085
+ stroke-linejoin="round"
18086
+ />
18087
+ </svg>
18088
+ </button>
18089
+ ${isOpen ? lit.html`
18090
+ <div
18091
+ class="segment-popup${this._flipUp ? " flip-up" : ""}"
18092
+ role="listbox"
18093
+ aria-label=${label}
18094
+ >
18095
+ ${range(max, step).map((n) => {
18096
+ const isSelected = parts ? parts[segment] === n : false;
18097
+ const optDisabled = this._isDisabled({ ...current, [segment]: n });
18098
+ return lit.html`<button
18099
+ type="button"
18100
+ role="option"
18101
+ aria-selected=${isSelected ? "true" : "false"}
18102
+ class="option${isSelected ? " selected" : ""}"
18103
+ ?disabled=${optDisabled}
18104
+ @click=${() => this._pick(segment, n)}
18105
+ >
18106
+ ${pad(n)}
18107
+ </button>`;
18108
+ })}
18109
+ </div>
18110
+ ` : lit.nothing}
18111
+ </div>
18112
+ `;
18113
+ }
18114
+ render() {
18115
+ return lit.html`
18116
+ <div part="base" class="field">
18117
+ ${this.label && !this.hideLabel ? lit.html`<label part="label" class="label">${this.label}</label>` : lit.nothing}
18118
+ <div part="segments" class="segments">
18119
+ ${this._renderSegment("h")}
18120
+ <span class="sep" aria-hidden="true">:</span>
18121
+ ${this._renderSegment("m")}
18122
+ ${this.showSeconds ? lit.html`<span class="sep" aria-hidden="true">:</span>${this._renderSegment("s")}` : lit.nothing}
18123
+ </div>
18124
+ ${this.validationHint ? lit.html`<span part="hint" class="hint">${this.validationHint}</span>` : lit.nothing}
18125
+ </div>
18126
+ `;
18127
+ }
18128
+ };
18129
+ exports.ArveaTimeSelect.styles = arveaTimeSelectStyles;
18130
+ __decorateClass([
18131
+ decorators_js.property({ type: String })
18132
+ ], exports.ArveaTimeSelect.prototype, "label", 2);
18133
+ __decorateClass([
18134
+ decorators_js.property({ type: Boolean, attribute: "hide-label" })
18135
+ ], exports.ArveaTimeSelect.prototype, "hideLabel", 2);
18136
+ __decorateClass([
18137
+ decorators_js.property({ type: String })
18138
+ ], exports.ArveaTimeSelect.prototype, "value", 2);
18139
+ __decorateClass([
18140
+ decorators_js.property({ type: Boolean, attribute: "show-seconds" })
18141
+ ], exports.ArveaTimeSelect.prototype, "showSeconds", 2);
18142
+ __decorateClass([
18143
+ decorators_js.property({ type: Number, attribute: "hour-step" })
18144
+ ], exports.ArveaTimeSelect.prototype, "hourStep", 2);
18145
+ __decorateClass([
18146
+ decorators_js.property({ type: Number, attribute: "minute-step" })
18147
+ ], exports.ArveaTimeSelect.prototype, "minuteStep", 2);
18148
+ __decorateClass([
18149
+ decorators_js.property({ type: Number, attribute: "second-step" })
18150
+ ], exports.ArveaTimeSelect.prototype, "secondStep", 2);
18151
+ __decorateClass([
18152
+ decorators_js.property({ type: String })
18153
+ ], exports.ArveaTimeSelect.prototype, "min", 2);
18154
+ __decorateClass([
18155
+ decorators_js.property({ type: String })
18156
+ ], exports.ArveaTimeSelect.prototype, "max", 2);
18157
+ __decorateClass([
18158
+ decorators_js.property({ type: Boolean, reflect: true })
18159
+ ], exports.ArveaTimeSelect.prototype, "disabled", 2);
18160
+ __decorateClass([
18161
+ decorators_js.property({ type: Boolean, reflect: true })
18162
+ ], exports.ArveaTimeSelect.prototype, "required", 2);
18163
+ __decorateClass([
18164
+ decorators_js.property({ type: Boolean, reflect: true })
18165
+ ], exports.ArveaTimeSelect.prototype, "invalid", 2);
18166
+ __decorateClass([
18167
+ decorators_js.property({ type: String, attribute: "validation-hint" })
18168
+ ], exports.ArveaTimeSelect.prototype, "validationHint", 2);
18169
+ __decorateClass([
18170
+ decorators_js.state()
18171
+ ], exports.ArveaTimeSelect.prototype, "_openSegment", 2);
18172
+ __decorateClass([
18173
+ decorators_js.state()
18174
+ ], exports.ArveaTimeSelect.prototype, "_flipUp", 2);
18175
+ exports.ArveaTimeSelect = __decorateClass([
18176
+ decorators_js.customElement("arvea-time-select")
18177
+ ], exports.ArveaTimeSelect);
17803
18178
  var arveaTreeStyles = [
17804
18179
  tokenStyles,
17805
18180
  lit.css`
@@ -18002,8 +18377,8 @@ exports.ArveaTree = class ArveaTree extends lit.LitElement {
18002
18377
  _toggleCheck(node) {
18003
18378
  const set = new Set(this._checkedSet);
18004
18379
  const childKeys = this._flattenChildKeys(node);
18005
- const state20 = this._checkState(node);
18006
- if (state20 === "all") {
18380
+ const state21 = this._checkState(node);
18381
+ if (state21 === "all") {
18007
18382
  set.delete(node.key);
18008
18383
  childKeys.forEach((k) => set.delete(k));
18009
18384
  } else {
@@ -18779,6 +19154,7 @@ exports.arveaTabsStyles = arveaTabsStyles;
18779
19154
  exports.arveaTagStyles = arveaTagStyles;
18780
19155
  exports.arveaTagsInputStyles = arveaTagsInputStyles;
18781
19156
  exports.arveaTextareaStyles = arveaTextareaStyles;
19157
+ exports.arveaTimeSelectStyles = arveaTimeSelectStyles;
18782
19158
  exports.arveaToastStyles = arveaToastStyles;
18783
19159
  exports.arveaToggleStyles = arveaToggleStyles;
18784
19160
  exports.arveaTooltipStyles = arveaTooltipStyles;