@wcstack/upload 4.0.0-rc.8 → 4.0.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/dist/index.esm.js CHANGED
@@ -849,6 +849,61 @@ function upgradeProperties(element) {
849
849
  }
850
850
  }
851
851
 
852
+ // ===========================================================================
853
+ // AUTO-GENERATED FILE - DO NOT EDIT.
854
+ // Generated from /protocol/input-attribute.ts by scripts/sync-protocol-types.mjs.
855
+ // Run `node scripts/sync-protocol-types.mjs` after editing the source.
856
+ // ===========================================================================
857
+ // 属性へ反映する wc-bindable 入力の producer 側(SPEC-extensions § Producer guidance for inputs の P1〜P3)。
858
+ // 入力の setter は属性をこの 2 関数で書く。それで次が揃う:
859
+ // - `undefined` は「値が無い」(P1): 属性を、この関数で最初に書く前の状態 — マークアップに書かれた値、
860
+ // 無ければ属性なし(= その入力の文書化した既定値)— へ戻す。applier プロファイルを宣言する binder は
861
+ // 値の後の `undefined` を書き(A2)、React 19 も書き、直接の代入でも届く。
862
+ // - `null` はクリア(P2): 属性なし、つまり文書化した既定値。
863
+ // - どちらも文字列 "undefined" / "null" として属性に入らない。
864
+ //
865
+ // 「最初に書く前」は、その最初の書き込みのときに読む(遅延)。upgrade 前に代入されたプロパティは
866
+ // connectedCallback の upgradeProperties() が通し直すので、そのときにはパーサが書いた属性が揃っている。
867
+ // 要素自身が setter を通さずに書いた属性は、最初の書き込みより前なら「最初の状態」に含まれる。
868
+ //
869
+ // SINGLE SOURCE OF TRUTH: edit only this file (/protocol/input-attribute.ts), then run
870
+ // `node scripts/sync-protocol-types.mjs` to regenerate the per-package copies
871
+ // (packages/<pkg>/src/protocol/inputAttribute.ts). Those copies are generated — do not edit them.
872
+ const initialAttributes = new WeakMap();
873
+ /** The attribute as it stood before the first write through these helpers. */
874
+ function initialAttribute(el, name) {
875
+ let byName = initialAttributes.get(el);
876
+ if (byName === undefined) {
877
+ byName = new Map();
878
+ initialAttributes.set(el, byName);
879
+ }
880
+ if (!byName.has(name))
881
+ byName.set(name, el.getAttribute(name));
882
+ return byName.get(name);
883
+ }
884
+ function writeAttribute(el, name, value) {
885
+ if (value === null)
886
+ el.removeAttribute(name);
887
+ else
888
+ el.setAttribute(name, value);
889
+ }
890
+ /**
891
+ * A value attribute. `value` is written as `String(value)`; `null` removes the attribute;
892
+ * `undefined` restores the attribute the element started with.
893
+ */
894
+ function reflectAttribute(el, name, value) {
895
+ const initial = initialAttribute(el, name);
896
+ writeAttribute(el, name, value === undefined ? initial : value === null ? null : String(value));
897
+ }
898
+ /**
899
+ * A boolean attribute, present while `value` is truthy (`null` and `false` remove it);
900
+ * `undefined` restores the attribute the element started with.
901
+ */
902
+ function reflectBooleanAttribute(el, name, value) {
903
+ const initial = initialAttribute(el, name);
904
+ writeAttribute(el, name, value === undefined ? initial : value ? "" : null);
905
+ }
906
+
852
907
  class WcsUpload extends HTMLElement {
853
908
  static hasConnectedCallbackPromise = true;
854
909
  static wcBindable = {
@@ -861,9 +916,9 @@ class WcsUpload extends HTMLElement {
861
916
  // Shell-level input surface. The Core declares only the portable `url` / `method` /
862
917
  // `fieldName`; the Shell adds the DOM-driven settable surface. No `attribute` hints
863
918
  // are given: the `url` / `method` / `fieldName` / `multiple` / `maxSize` / `accept` /
864
- // `manual` setters already reflect to their attributes, so a binding system that
865
- // mirrors inputs[].attribute would set the attribute twice (`files` / `trigger` are
866
- // not attribute-backed). `commands` (upload / abort) are inherited unchanged from the
919
+ // `manual` setters reflect to their attributes themselves, and a binding system that
920
+ // mirrored inputs[].attribute (@wcstack/state 3.x) would set the attribute twice
921
+ // (`files` / `trigger` are not attribute-backed). `commands` (upload / abort) are inherited unchanged from the
867
922
  // Core via the spread above.
868
923
  inputs: [
869
924
  { name: "url" },
@@ -947,34 +1002,34 @@ class WcsUpload extends HTMLElement {
947
1002
  return this._connectedCallbackPromise;
948
1003
  }
949
1004
  // --- Attribute accessors ---
1005
+ //
1006
+ // setter は null / undefined を setAttribute に文字列化させない("undefined" の url へ
1007
+ // 送信したり、"null" の method を使ったりしないため)。`null` は属性を外して既定値に戻し、
1008
+ // `undefined` は要素が最初に持っていた属性へ戻す(wc-bindable producer guidance P1。
1009
+ // React 19 や直接の代入は undefined を書く。@wcstack/state は書かない)。
950
1010
  get url() {
951
1011
  return this.getAttribute("url") || "";
952
1012
  }
953
1013
  set url(value) {
954
- this.setAttribute("url", value);
1014
+ reflectAttribute(this, "url", value);
955
1015
  }
956
1016
  get method() {
957
1017
  return (this.getAttribute("method") || "POST").toUpperCase();
958
1018
  }
959
1019
  set method(value) {
960
- this.setAttribute("method", value);
1020
+ reflectAttribute(this, "method", value);
961
1021
  }
962
1022
  get fieldName() {
963
1023
  return this.getAttribute("field-name") || "file";
964
1024
  }
965
1025
  set fieldName(value) {
966
- this.setAttribute("field-name", value);
1026
+ reflectAttribute(this, "field-name", value);
967
1027
  }
968
1028
  get multiple() {
969
1029
  return this.hasAttribute("multiple");
970
1030
  }
971
1031
  set multiple(value) {
972
- if (value) {
973
- this.setAttribute("multiple", "");
974
- }
975
- else {
976
- this.removeAttribute("multiple");
977
- }
1032
+ reflectBooleanAttribute(this, "multiple", value);
978
1033
  }
979
1034
  get maxSize() {
980
1035
  const attr = this.getAttribute("max-size");
@@ -988,24 +1043,19 @@ class WcsUpload extends HTMLElement {
988
1043
  return Number.isFinite(n) && n >= 0 ? n : Infinity;
989
1044
  }
990
1045
  set maxSize(value) {
991
- this.setAttribute("max-size", String(value));
1046
+ reflectAttribute(this, "max-size", value);
992
1047
  }
993
1048
  get accept() {
994
1049
  return this.getAttribute("accept") || "";
995
1050
  }
996
1051
  set accept(value) {
997
- this.setAttribute("accept", value);
1052
+ reflectAttribute(this, "accept", value);
998
1053
  }
999
1054
  get manual() {
1000
1055
  return this.hasAttribute("manual");
1001
1056
  }
1002
1057
  set manual(value) {
1003
- if (value) {
1004
- this.setAttribute("manual", "");
1005
- }
1006
- else {
1007
- this.removeAttribute("manual");
1008
- }
1058
+ reflectBooleanAttribute(this, "manual", value);
1009
1059
  }
1010
1060
  // --- Core delegated getters ---
1011
1061
  get value() {
@@ -1054,12 +1104,15 @@ class WcsUpload extends HTMLElement {
1054
1104
  return this._files;
1055
1105
  }
1056
1106
  set files(value) {
1057
- this._files = value;
1107
+ // undefined は「値が無い」= 初期状態(null)。null と同じく files をクリアし、
1108
+ // files-changed にも undefined ではなく null を載せる。
1109
+ const files = value ?? null;
1110
+ this._files = files;
1058
1111
  this.dispatchEvent(new CustomEvent("wcs-upload:files-changed", {
1059
- detail: value,
1112
+ detail: files,
1060
1113
  bubbles: true,
1061
1114
  }));
1062
- if (!this.manual && this.url && value && value.length > 0) {
1115
+ if (!this.manual && this.url && files && files.length > 0) {
1063
1116
  this.upload();
1064
1117
  }
1065
1118
  }