Changeset 3778841
- Timestamp:
- 11/02/2026 02:28:51 AM (3 hours ago)
- Location:
- chiseiko-essential-swatches
- Files:
-
- 122 added
- 22 edited
-
tags/1.1.0 (added)
-
tags/1.1.0/assets (added)
-
tags/1.1.0/assets/css (added)
-
tags/1.1.0/assets/css/chiseikoessw-admin.css (added)
-
tags/1.1.0/assets/css/chiseikoessw-admin.min.css (added)
-
tags/1.1.0/assets/css/chiseikoessw-archive.css (added)
-
tags/1.1.0/assets/css/chiseikoessw-archive.min.css (added)
-
tags/1.1.0/assets/css/chiseikoessw-card-swatches.css (added)
-
tags/1.1.0/assets/css/chiseikoessw-card-swatches.min.css (added)
-
tags/1.1.0/assets/css/chiseikoessw-frontend.css (added)
-
tags/1.1.0/assets/css/chiseikoessw-frontend.min.css (added)
-
tags/1.1.0/assets/css/chiseikoessw-layout.css (added)
-
tags/1.1.0/assets/css/chiseikoessw-layout.min.css (added)
-
tags/1.1.0/assets/css/chiseikoessw-single.css (added)
-
tags/1.1.0/assets/css/chiseikoessw-single.min.css (added)
-
tags/1.1.0/assets/css/chiseikoessw-user-guide.css (added)
-
tags/1.1.0/assets/css/chiseikoessw-user-guide.min.css (added)
-
tags/1.1.0/assets/css/index.php (added)
-
tags/1.1.0/assets/img (added)
-
tags/1.1.0/assets/img/chiseikoessw-logo.svg (added)
-
tags/1.1.0/assets/img/index.php (added)
-
tags/1.1.0/assets/index.php (added)
-
tags/1.1.0/assets/js (added)
-
tags/1.1.0/assets/js/chiseikoessw-admin-bridge.js (added)
-
tags/1.1.0/assets/js/chiseikoessw-admin-bridge.min.js (added)
-
tags/1.1.0/assets/js/chiseikoessw-admin.js (added)
-
tags/1.1.0/assets/js/chiseikoessw-admin.min.js (added)
-
tags/1.1.0/assets/js/chiseikoessw-archive-shared.js (added)
-
tags/1.1.0/assets/js/chiseikoessw-archive-shared.min.js (added)
-
tags/1.1.0/assets/js/chiseikoessw-archive.js (added)
-
tags/1.1.0/assets/js/chiseikoessw-archive.min.js (added)
-
tags/1.1.0/assets/js/chiseikoessw-batch.js (added)
-
tags/1.1.0/assets/js/chiseikoessw-batch.min.js (added)
-
tags/1.1.0/assets/js/chiseikoessw-frontend.js (added)
-
tags/1.1.0/assets/js/chiseikoessw-frontend.min.js (added)
-
tags/1.1.0/assets/js/chiseikoessw-layout.js (added)
-
tags/1.1.0/assets/js/chiseikoessw-layout.min.js (added)
-
tags/1.1.0/assets/js/chiseikoessw-review-notice.js (added)
-
tags/1.1.0/assets/js/chiseikoessw-review-notice.min.js (added)
-
tags/1.1.0/assets/js/chiseikoessw-settings-toggle.js (added)
-
tags/1.1.0/assets/js/chiseikoessw-settings-toggle.min.js (added)
-
tags/1.1.0/assets/js/chiseikoessw-tooltip.js (added)
-
tags/1.1.0/assets/js/chiseikoessw-tooltip.min.js (added)
-
tags/1.1.0/assets/js/chiseikoessw-utils.js (added)
-
tags/1.1.0/assets/js/chiseikoessw-utils.min.js (added)
-
tags/1.1.0/assets/js/index.php (added)
-
tags/1.1.0/chiseiko-essential-swatches.php (added)
-
tags/1.1.0/docs (added)
-
tags/1.1.0/docs/chapters.json (added)
-
tags/1.1.0/docs/creating-attributes.html (added)
-
tags/1.1.0/docs/customizing-swatches.html (added)
-
tags/1.1.0/docs/images (added)
-
tags/1.1.0/docs/images/01-installation (added)
-
tags/1.1.0/docs/images/01-installation/plugins-active.webp (added)
-
tags/1.1.0/docs/images/01-installation/pro-menu.webp (added)
-
tags/1.1.0/docs/images/01-installation/upload-plugin.webp (added)
-
tags/1.1.0/docs/images/02-creating-attributes (added)
-
tags/1.1.0/docs/images/02-creating-attributes/add-term-color.webp (added)
-
tags/1.1.0/docs/images/02-creating-attributes/attributes-screen.webp (added)
-
tags/1.1.0/docs/images/02-creating-attributes/color-picker-open.webp (added)
-
tags/1.1.0/docs/images/02-creating-attributes/configure-terms-link.webp (added)
-
tags/1.1.0/docs/images/02-creating-attributes/image-swatch-button.webp (added)
-
tags/1.1.0/docs/images/02-creating-attributes/terms-list-swatch-column.webp (added)
-
tags/1.1.0/docs/images/free (added)
-
tags/1.1.0/docs/images/free/archive-interactive.webp (added)
-
tags/1.1.0/docs/images/free/archive-strip.webp (added)
-
tags/1.1.0/docs/images/free/pdp-multi-attribute.webp (added)
-
tags/1.1.0/docs/images/free/pdp-swatches.webp (added)
-
tags/1.1.0/docs/images/free/settings-product-page.webp (added)
-
tags/1.1.0/docs/images/free/settings.webp (added)
-
tags/1.1.0/docs/images/pro (added)
-
tags/1.1.0/docs/images/pro/license-no-license.webp (added)
-
tags/1.1.0/docs/images/pro/product-attributes-tab.webp (added)
-
tags/1.1.0/docs/images/pro/product-variations-tab.webp (added)
-
tags/1.1.0/docs/installation.html (added)
-
tags/1.1.0/docs/settings.html (added)
-
tags/1.1.0/docs/variable-products.html (added)
-
tags/1.1.0/includes (added)
-
tags/1.1.0/includes/class-chiseikoessw-admin-term-meta-renderer.php (added)
-
tags/1.1.0/includes/class-chiseikoessw-admin.php (added)
-
tags/1.1.0/includes/class-chiseikoessw-ajax-batch.php (added)
-
tags/1.1.0/includes/class-chiseikoessw-appearance.php (added)
-
tags/1.1.0/includes/class-chiseikoessw-archive-swatches.php (added)
-
tags/1.1.0/includes/class-chiseikoessw-asset-cachebust.php (added)
-
tags/1.1.0/includes/class-chiseikoessw-attribute-defaults.php (added)
-
tags/1.1.0/includes/class-chiseikoessw-card-swatch-renderer.php (added)
-
tags/1.1.0/includes/class-chiseikoessw-catalog-mode.php (added)
-
tags/1.1.0/includes/class-chiseikoessw-config.php (added)
-
tags/1.1.0/includes/class-chiseikoessw-frontend-archive-button-handler.php (added)
-
tags/1.1.0/includes/class-chiseikoessw-frontend-attribute-swatch-resolver.php (added)
-
tags/1.1.0/includes/class-chiseikoessw-frontend-loop-renderer.php (added)
-
tags/1.1.0/includes/class-chiseikoessw-frontend-swatch-output-assembler.php (added)
-
tags/1.1.0/includes/class-chiseikoessw-frontend.php (added)
-
tags/1.1.0/includes/class-chiseikoessw-hooks.php (added)
-
tags/1.1.0/includes/class-chiseikoessw-image-preview.php (added)
-
tags/1.1.0/includes/class-chiseikoessw-mobile-scroll.php (added)
-
tags/1.1.0/includes/class-chiseikoessw-onboarding-notice.php (added)
-
tags/1.1.0/includes/class-chiseikoessw-plugin-links.php (added)
-
tags/1.1.0/includes/class-chiseikoessw-rate-limiter.php (added)
-
tags/1.1.0/includes/class-chiseikoessw-render-guard.php (added)
-
tags/1.1.0/includes/class-chiseikoessw-review-notice.php (added)
-
tags/1.1.0/includes/class-chiseikoessw-route.php (added)
-
tags/1.1.0/includes/class-chiseikoessw-settings.php (added)
-
tags/1.1.0/includes/class-chiseikoessw-swatch-context.php (added)
-
tags/1.1.0/includes/class-chiseikoessw-swatch-layout.php (added)
-
tags/1.1.0/includes/class-chiseikoessw-term-meta.php (added)
-
tags/1.1.0/includes/class-chiseikoessw-user-guide.php (added)
-
tags/1.1.0/includes/class-chiseikoessw-variation-utils.php (added)
-
tags/1.1.0/includes/index.php (added)
-
tags/1.1.0/index.php (added)
-
tags/1.1.0/languages (added)
-
tags/1.1.0/languages/index.php (added)
-
tags/1.1.0/readme.txt (added)
-
tags/1.1.0/uninstall.php (added)
-
trunk/assets/css/chiseikoessw-archive.css (modified) (2 diffs)
-
trunk/assets/css/chiseikoessw-archive.min.css (modified) (1 diff)
-
trunk/assets/css/chiseikoessw-frontend.css (modified) (1 diff)
-
trunk/assets/css/chiseikoessw-frontend.min.css (modified) (1 diff)
-
trunk/assets/js/chiseikoessw-frontend.js (modified) (1 diff)
-
trunk/assets/js/chiseikoessw-frontend.min.js (modified) (1 diff)
-
trunk/assets/js/chiseikoessw-review-notice.js (added)
-
trunk/assets/js/chiseikoessw-review-notice.min.js (added)
-
trunk/assets/js/chiseikoessw-utils.js (modified) (1 diff)
-
trunk/assets/js/chiseikoessw-utils.min.js (modified) (1 diff)
-
trunk/chiseiko-essential-swatches.php (modified) (4 diffs)
-
trunk/docs/chapters.json (modified) (4 diffs)
-
trunk/docs/creating-attributes.html (modified) (2 diffs)
-
trunk/docs/customizing-swatches.html (added)
-
trunk/docs/installation.html (modified) (2 diffs)
-
trunk/docs/settings.html (modified) (5 diffs)
-
trunk/docs/variable-products.html (modified) (2 diffs)
-
trunk/includes/class-chiseikoessw-ajax-batch.php (modified) (1 diff)
-
trunk/includes/class-chiseikoessw-appearance.php (added)
-
trunk/includes/class-chiseikoessw-attribute-defaults.php (added)
-
trunk/includes/class-chiseikoessw-frontend.php (modified) (1 diff)
-
trunk/includes/class-chiseikoessw-onboarding-notice.php (added)
-
trunk/includes/class-chiseikoessw-plugin-links.php (added)
-
trunk/includes/class-chiseikoessw-review-notice.php (added)
-
trunk/includes/class-chiseikoessw-settings.php (modified) (2 diffs)
-
trunk/includes/class-chiseikoessw-swatch-layout.php (modified) (2 diffs)
-
trunk/includes/class-chiseikoessw-term-meta.php (modified) (2 diffs)
-
trunk/includes/class-chiseikoessw-user-guide.php (modified) (3 diffs)
-
trunk/readme.txt (modified) (3 diffs)
-
trunk/uninstall.php (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
chiseiko-essential-swatches/trunk/assets/css/chiseikoessw-archive.css
r3598460 r3778841 38 38 align-self: stretch; 39 39 box-sizing: border-box; 40 /* Swatches never widen the product card. Without this, a long label's 41 * min-content widens its column in grid themes (Astra's 42 * `repeat(4, 1fr)` went 479/280/205/479 px instead of 4 × 285 px). */ 43 contain: inline-size; 40 44 } 41 45 … … 146 150 } 147 151 152 /* A label wider than the card (Pro Pill/Square, or the chapter 25 CSS) 153 * shrinks to the card and ends in an ellipsis; the button's accessible name 154 * and tooltip keep the full term name. */ 155 .chiseikoessw-swatch--loop { 156 max-width: 100%; 157 } 158 159 .chiseikoessw-swatch--loop .chiseikoessw-swatch__inner--text { 160 min-width: 0; 161 overflow: hidden; 162 text-overflow: ellipsis; 163 } 164 148 165 /* Ensure light / white color swatches remain visible against white cards */ 149 166 .chiseikoessw-swatch--loop.chiseikoessw-swatch--color .chiseikoessw-swatch__inner { -
chiseiko-essential-swatches/trunk/assets/css/chiseikoessw-archive.min.css
r3598460 r3778841 1 .chiseikoessw-card-swatches{display:flex;flex-direction:column;align-items:var(--chiseikoessw-archive-align,center);gap:6px;margin:6px 0 0;padding:8px 16px 16px;border-top:1px solid rgba(0,0,0,.1);width:100%;align-self:stretch;box-sizing:border-box }.chiseikoessw-card-swatches__row--variable{display:flex;flex-wrap:wrap;gap:5px;align-items:center;justify-content:var(--chiseikoessw-archive-align,center);padding:4px;box-sizing:border-box;contain:layout style;max-height:calc(var(--chiseikoessw-swatch-size-sm) * 2 + 5px + 8px + 8px);overflow:hidden}.chiseikoessw-accordion__panel .chiseikoessw-card-swatches__row--variable,.chiseikoessw-card-swatches__row--variable.chiseikoessw-overflow-ready{max-height:none;overflow:visible}.chiseikoessw-swatch--loop{width:var(--chiseikoessw-swatch-size-sm)!important;height:var(--chiseikoessw-swatch-size-sm)!important;min-width:var(--chiseikoessw-swatch-size-sm)!important;min-height:var(--chiseikoessw-swatch-size-sm)!important;box-sizing:border-box;border-radius:50%;cursor:default;pointer-events:none;box-shadow:0 0 0 1px rgba(0,0,0,.12);border:var(--chiseikoessw-swatch-border-width) solid transparent;outline:transparent solid 2px;outline-offset:2px;transform:none!important;display:inline-flex;align-items:center;justify-content:center;flex-shrink:0}.chiseikoessw-swatch--loop:hover{transform:none!important;box-shadow:0 0 0 1px rgba(0,0,0,.12)!important}.chiseikoessw-swatch--loop.chiseikoessw-swatch--label,.chiseikoessw-swatch--loop.chiseikoessw-swatch--none,.chiseikoessw-swatch--loop.chiseikoessw-swatch--text{background:#f5f5f5;color:#333;font-size:9px;font-weight:600;letter-spacing:.01em;white-space:nowrap;overflow:hidden;padding:0}.chiseikoessw-swatch--loop .chiseikoessw-swatch__inner{border-radius:inherit}.chiseikoessw-swatch--loop .chiseikoessw-swatch__inner--text{width:auto;height:auto;border-radius:0;font-size:inherit;line-height:1}.chiseikoessw-swatch--loop.chiseikoessw-swatch--color .chiseikoessw-swatch__inner{box-shadow:inset 0 0 0 1px rgba(0,0,0,.08)}.chiseikoessw-swatch--loop img{border-radius:inherit}.chiseikoessw-swatch-btn.chiseikoessw-swatch--radio.chiseikoessw-selected{background:linear-gradient(180deg,#fff 0,#eef4ff 100%);box-shadow:0 1px 2px rgba(15,23,42,.12),inset 0 1px 0 rgba(255,255,255,.92)}.chiseikoessw-swatch-btn.chiseikoessw-selected .chiseikoessw-swatch__inner{box-shadow:var(--chiseikoessw-swatch-selected-inset)}.chiseikoessw-swatch-btn[data-chiseikoessw-interactive="1"]{cursor:pointer;pointer-events:auto}.chiseikoessw-swatch-btn[data-chiseikoessw-interactive="1"][aria-disabled=true]{cursor:not-allowed;pointer-events:none}.chiseikoessw-swatch-btn[data-chiseikoessw-interactive="1"]:focus-visible,.chiseikoessw-swatch-btn[data-chiseikoessw-interactive="1"]:hover{outline:currentColor solid 2px;outline-offset:2px}.chiseikoessw-swatch-btn.chiseikoessw-swatch--radio[data-chiseikoessw-interactive="1"]:focus-visible,.chiseikoessw-swatch-btn.chiseikoessw-swatch--radio[data-chiseikoessw-interactive="1"]:hover{background:rgba(15,23,42,.04);box-shadow:0 1px 2px rgba(15,23,42,.1),inset 0 1px 0 rgba(255,255,255,.92)}.chiseikoessw-swatch-btn.chiseikoessw-swatch--radio[data-chiseikoessw-interactive="1"]:focus-visible .chiseikoessw-radio-dot,.chiseikoessw-swatch-btn.chiseikoessw-swatch--radio[data-chiseikoessw-interactive="1"]:hover .chiseikoessw-radio-dot{border-color:var(--chiseikoessw-accent,currentColor)}.chiseikoessw-swatch-btn.chiseikoessw-swatch--radio.chiseikoessw-selected[data-chiseikoessw-interactive="1"]:focus-visible,.chiseikoessw-swatch-btn.chiseikoessw-swatch--radio.chiseikoessw-selected[data-chiseikoessw-interactive="1"]:hover{background:linear-gradient(180deg,#fff 0,#eef4ff 100%);box-shadow:0 1px 2px rgba(15,23,42,.12),inset 0 1px 0 rgba(255,255,255,.92)}@supports (color:color-mix(in srgb,red 50%,blue)){.chiseikoessw-swatch-btn.chiseikoessw-swatch--radio[data-chiseikoessw-interactive="1"]:focus-visible,.chiseikoessw-swatch-btn.chiseikoessw-swatch--radio[data-chiseikoessw-interactive="1"]:hover{background:color-mix(in srgb,var(--chiseikoessw-accent,currentColor) 10%,#fff)}.chiseikoessw-swatch-btn.chiseikoessw-swatch--radio.chiseikoessw-selected[data-chiseikoessw-interactive="1"]:focus-visible,.chiseikoessw-swatch-btn.chiseikoessw-swatch--radio.chiseikoessw-selected[data-chiseikoessw-interactive="1"]:hover{background:linear-gradient(180deg,#fff 0,#eef4ff 100%)}}.chiseikoessw-archive-cta{cursor:pointer;text-decoration:none}.chiseikoessw-archive-cta:hover{filter:brightness(.92);transform:translateY(-1px);box-shadow:0 4px 10px rgba(0,0,0,.2)}.chiseikoessw-archive-cta.is-loading,.chiseikoessw-archive-cta[disabled]{transform:none;filter:none;box-shadow:none}.chiseikoessw-archive-cta[disabled]{opacity:.55;cursor:not-allowed}.chiseikoessw-archive-cta.is-loading{opacity:.7;cursor:wait}.chiseikoessw-archive-view-cart{display:block;margin-top:6px;text-align:center;font-size:12px;letter-spacing:.04em;color:var(--chiseikoessw-accent,currentColor);text-decoration:underline;text-underline-offset:2px}.chiseikoessw-archive-view-cart:hover{color:var(--chiseikoessw-accent-dark,currentColor)}[data-chiseikoessw-hidden="1"]{display:none!important}.chiseikoessw-arch-updating img{opacity:.5;transition:opacity .15s}@media (prefers-reduced-motion:reduce){.chiseikoessw-arch-updating img,.chiseikoessw-archive-cta,.chiseikoessw-swatch-btn[data-chiseikoessw-interactive="1"]{transition:none;transform:none!important;filter:none!important}}@media (forced-colors:active){.chiseikoessw-archive-cta{border:2px solid ButtonText;background:ButtonFace;color:ButtonText;text-shadow:none}}.chiseikoessw-atc-error{color:var(--chiseikoessw-error,#a00);font-size:.85em;margin-top:4px}1 .chiseikoessw-card-swatches{display:flex;flex-direction:column;align-items:var(--chiseikoessw-archive-align,center);gap:6px;margin:6px 0 0;padding:8px 16px 16px;border-top:1px solid rgba(0,0,0,.1);width:100%;align-self:stretch;box-sizing:border-box;contain:inline-size}.chiseikoessw-card-swatches__row--variable{display:flex;flex-wrap:wrap;gap:5px;align-items:center;justify-content:var(--chiseikoessw-archive-align,center);padding:4px;box-sizing:border-box;contain:layout style;max-height:calc(var(--chiseikoessw-swatch-size-sm) * 2 + 5px + 8px + 8px);overflow:hidden}.chiseikoessw-accordion__panel .chiseikoessw-card-swatches__row--variable,.chiseikoessw-card-swatches__row--variable.chiseikoessw-overflow-ready{max-height:none;overflow:visible}.chiseikoessw-swatch--loop{width:var(--chiseikoessw-swatch-size-sm)!important;height:var(--chiseikoessw-swatch-size-sm)!important;min-width:var(--chiseikoessw-swatch-size-sm)!important;min-height:var(--chiseikoessw-swatch-size-sm)!important;box-sizing:border-box;border-radius:50%;cursor:default;pointer-events:none;box-shadow:0 0 0 1px rgba(0,0,0,.12);border:var(--chiseikoessw-swatch-border-width) solid transparent;outline:transparent solid 2px;outline-offset:2px;transform:none!important;display:inline-flex;align-items:center;justify-content:center;flex-shrink:0;max-width:100%}.chiseikoessw-swatch--loop:hover{transform:none!important;box-shadow:0 0 0 1px rgba(0,0,0,.12)!important}.chiseikoessw-swatch--loop.chiseikoessw-swatch--label,.chiseikoessw-swatch--loop.chiseikoessw-swatch--none,.chiseikoessw-swatch--loop.chiseikoessw-swatch--text{background:#f5f5f5;color:#333;font-size:9px;font-weight:600;letter-spacing:.01em;white-space:nowrap;overflow:hidden;padding:0}.chiseikoessw-swatch--loop .chiseikoessw-swatch__inner{border-radius:inherit}.chiseikoessw-swatch--loop .chiseikoessw-swatch__inner--text{width:auto;height:auto;border-radius:0;font-size:inherit;line-height:1;min-width:0;overflow:hidden;text-overflow:ellipsis}.chiseikoessw-swatch--loop.chiseikoessw-swatch--color .chiseikoessw-swatch__inner{box-shadow:inset 0 0 0 1px rgba(0,0,0,.08)}.chiseikoessw-swatch--loop img{border-radius:inherit}.chiseikoessw-swatch-btn.chiseikoessw-swatch--radio.chiseikoessw-selected{background:linear-gradient(180deg,#fff 0,#eef4ff 100%);box-shadow:0 1px 2px rgba(15,23,42,.12),inset 0 1px 0 rgba(255,255,255,.92)}.chiseikoessw-swatch-btn.chiseikoessw-selected .chiseikoessw-swatch__inner{box-shadow:var(--chiseikoessw-swatch-selected-inset)}.chiseikoessw-swatch-btn[data-chiseikoessw-interactive="1"]{cursor:pointer;pointer-events:auto}.chiseikoessw-swatch-btn[data-chiseikoessw-interactive="1"][aria-disabled=true]{cursor:not-allowed;pointer-events:none}.chiseikoessw-swatch-btn[data-chiseikoessw-interactive="1"]:focus-visible,.chiseikoessw-swatch-btn[data-chiseikoessw-interactive="1"]:hover{outline:currentColor solid 2px;outline-offset:2px}.chiseikoessw-swatch-btn.chiseikoessw-swatch--radio[data-chiseikoessw-interactive="1"]:focus-visible,.chiseikoessw-swatch-btn.chiseikoessw-swatch--radio[data-chiseikoessw-interactive="1"]:hover{background:rgba(15,23,42,.04);box-shadow:0 1px 2px rgba(15,23,42,.1),inset 0 1px 0 rgba(255,255,255,.92)}.chiseikoessw-swatch-btn.chiseikoessw-swatch--radio[data-chiseikoessw-interactive="1"]:focus-visible .chiseikoessw-radio-dot,.chiseikoessw-swatch-btn.chiseikoessw-swatch--radio[data-chiseikoessw-interactive="1"]:hover .chiseikoessw-radio-dot{border-color:var(--chiseikoessw-accent,currentColor)}.chiseikoessw-swatch-btn.chiseikoessw-swatch--radio.chiseikoessw-selected[data-chiseikoessw-interactive="1"]:focus-visible,.chiseikoessw-swatch-btn.chiseikoessw-swatch--radio.chiseikoessw-selected[data-chiseikoessw-interactive="1"]:hover{background:linear-gradient(180deg,#fff 0,#eef4ff 100%);box-shadow:0 1px 2px rgba(15,23,42,.12),inset 0 1px 0 rgba(255,255,255,.92)}@supports (color:color-mix(in srgb,red 50%,blue)){.chiseikoessw-swatch-btn.chiseikoessw-swatch--radio[data-chiseikoessw-interactive="1"]:focus-visible,.chiseikoessw-swatch-btn.chiseikoessw-swatch--radio[data-chiseikoessw-interactive="1"]:hover{background:color-mix(in srgb,var(--chiseikoessw-accent,currentColor) 10%,#fff)}.chiseikoessw-swatch-btn.chiseikoessw-swatch--radio.chiseikoessw-selected[data-chiseikoessw-interactive="1"]:focus-visible,.chiseikoessw-swatch-btn.chiseikoessw-swatch--radio.chiseikoessw-selected[data-chiseikoessw-interactive="1"]:hover{background:linear-gradient(180deg,#fff 0,#eef4ff 100%)}}.chiseikoessw-archive-cta{cursor:pointer;text-decoration:none}.chiseikoessw-archive-cta:hover{filter:brightness(.92);transform:translateY(-1px);box-shadow:0 4px 10px rgba(0,0,0,.2)}.chiseikoessw-archive-cta.is-loading,.chiseikoessw-archive-cta[disabled]{transform:none;filter:none;box-shadow:none}.chiseikoessw-archive-cta[disabled]{opacity:.55;cursor:not-allowed}.chiseikoessw-archive-cta.is-loading{opacity:.7;cursor:wait}.chiseikoessw-archive-view-cart{display:block;margin-top:6px;text-align:center;font-size:12px;letter-spacing:.04em;color:var(--chiseikoessw-accent,currentColor);text-decoration:underline;text-underline-offset:2px}.chiseikoessw-archive-view-cart:hover{color:var(--chiseikoessw-accent-dark,currentColor)}[data-chiseikoessw-hidden="1"]{display:none!important}.chiseikoessw-arch-updating img{opacity:.5;transition:opacity .15s}@media (prefers-reduced-motion:reduce){.chiseikoessw-arch-updating img,.chiseikoessw-archive-cta,.chiseikoessw-swatch-btn[data-chiseikoessw-interactive="1"]{transition:none;transform:none!important;filter:none!important}}@media (forced-colors:active){.chiseikoessw-archive-cta{border:2px solid ButtonText;background:ButtonFace;color:ButtonText;text-shadow:none}}.chiseikoessw-atc-error{color:var(--chiseikoessw-error,#a00);font-size:.85em;margin-top:4px} -
chiseiko-essential-swatches/trunk/assets/css/chiseikoessw-frontend.css
r3598460 r3778841 270 270 } 271 271 272 /* ── Free global shape ───────────────────────────────────────────────────────── */ 273 /* 274 * The one place the Free "Swatch shape" setting is styled. CHISEIKOESSW_Appearance 275 * adds `chiseikoessw-free-shape-{shape}` to every swatch through 276 * `chiseikoessw_swatch_button_classes`, so product pages, shop/category cards 277 * and related cards all follow it. Circle is the default above and has no 278 * class; radio swatches never get one. The class is never added while Pro 279 * styling is active, so these rules cannot reach a licensed Pro store. 280 * Two classes beat the archive's single-class `border-radius: 50%`; label 281 * widths need !important to undo the archive's fixed-width loop rule. 282 */ 283 .chiseikoessw-swatch.chiseikoessw-free-shape-rounded { 284 border-radius: 6px; 285 } 286 287 .chiseikoessw-swatch.chiseikoessw-free-shape-square { 288 border-radius: 0; 289 } 290 291 /* Rounded / square label swatches widen to fit their text. */ 292 .chiseikoessw-swatch[class*="chiseikoessw-free-shape-"]:is(.chiseikoessw-swatch--label, .chiseikoessw-swatch--none) { 293 width: auto !important; 294 padding: var(--chiseikoessw-text-padding) !important; 295 } 296 297 .chiseikoessw-swatch--loop[class*="chiseikoessw-free-shape-"]:is(.chiseikoessw-swatch--label, .chiseikoessw-swatch--none) { 298 padding: var(--chiseikoessw-text-padding-sm) !important; 299 } 300 272 301 /* ── Text / fallback swatch (full-size interactive) ────────────────────────── */ 273 302 /* -
chiseiko-essential-swatches/trunk/assets/css/chiseikoessw-frontend.min.css
r3598460 r3778841 1 :root{--chiseikoessw-swatch-size:32px;--chiseikoessw-swatch-size-sm:32px;--chiseikoessw-swatch-radius:50%;--chiseikoessw-swatch-gap:8px;--chiseikoessw-swatch-gap-sm:6px;--chiseikoessw-text-height:32px;--chiseikoessw-text-min-width:32px;--chiseikoessw-text-padding:0 12px;--chiseikoessw-text-height-sm:32px;--chiseikoessw-text-min-width-sm:32px;--chiseikoessw-text-padding-sm:0 8px;--chiseikoessw-text-font-size:0.75rem;--chiseikoessw-text-font-weight:600;--chiseikoessw-text-white-space:nowrap;--chiseikoessw-linked-justify:flex-start;--chiseikoessw-radio-dot:16px;--chiseikoessw-radio-min:32px;--chiseikoessw-radio-padding:0 14px;--chiseikoessw-swatch-border-width:1px;--chiseikoessw-swatch-border-color:rgba(0, 0, 0, 0.12);--chiseikoessw-transition-speed:0.2s;--chiseikoessw-transition-ease:cubic-bezier(0.22, 0.61, 0.36, 1);--chiseikoessw-swatch-shadow:0 1px 3px rgba(0, 0, 0, .08);--chiseikoessw-swatch-hover-scale:1.08;--chiseikoessw-swatch-hover-z:2;--chiseikoessw-swatch-selected-inset:inset 0 0 0 2px rgba(255, 255, 255, .55);--chiseikoessw-swatch-selected-shadow:0 0 0 2px var(--chiseikoessw-accent, currentColor);--chiseikoessw-swatch-disabled-opacity:0.45}@media (pointer:coarse),(max-width:768px){:root{--chiseikoessw-swatch-size:44px;--chiseikoessw-swatch-size-sm:44px;--chiseikoessw-text-height:48px;--chiseikoessw-text-min-width:48px;--chiseikoessw-text-padding:0 16px;--chiseikoessw-text-height-sm:48px;--chiseikoessw-text-min-width-sm:48px;--chiseikoessw-text-padding-sm:0 12px;--chiseikoessw-radio-dot:20px;--chiseikoessw-radio-min:48px;--chiseikoessw-radio-padding:0 16px}}.chiseikoessw-native-select{position:absolute!important;width:1px!important;height:1px!important;max-width:1px!important;max-height:1px!important;min-width:0!important;min-height:0!important;overflow:hidden!important;clip:rect(0 0 0 0)!important;clip-path:inset(50%)!important;white-space:nowrap!important;border:0!important}.chiseikoessw-swatches{display:flex;flex-wrap:wrap;gap:var(--chiseikoessw-swatch-gap,8px);margin:4px 0;padding:0;list-style:none;contain:layout style}.chiseikoessw-swatch{appearance:none;background:0 0;border:var(--chiseikoessw-swatch-border-width) solid var(--chiseikoessw-swatch-border-color);padding:0;cursor:pointer;display:inline-flex;align-items:center;justify-content:center;flex-shrink:0;box-sizing:border-box;width:var(--chiseikoessw-swatch-size);height:var(--chiseikoessw-swatch-size);border-radius:var(--chiseikoessw-swatch-radius);transition:transform var(--chiseikoessw-transition-speed) var(--chiseikoessw-transition-ease, ease),opacity var(--chiseikoessw-transition-speed) var(--chiseikoessw-transition-ease, ease),box-shadow var(--chiseikoessw-transition-speed) var(--chiseikoessw-transition-ease, ease);box-shadow:var(--chiseikoessw-swatch-shadow);position:relative;overflow:hidden;outline:transparent solid 2px;outline-offset:2px}.chiseikoessw-swatch__inner{display:block;width:100%;height:100%;border-radius:inherit;overflow:hidden;pointer-events:none}.chiseikoessw-swatch--image .chiseikoessw-swatch__inner,.chiseikoessw-swatch--image img{display:block;width:100%;height:100%;object-fit:cover;border-radius:inherit}.chiseikoessw-swatch --disabled,.chiseikoessw-swatch[aria-disabled=true]{opacity:var(--chiseikoessw-swatch-disabled-opacity);cursor:not-allowed;transform:none!important}.chiseikoessw-swatch--disabled::after,.chiseikoessw-swatch[aria-disabled=true]::after{content:"";position:absolute;top:50%;left:-10%;width:120%;height:0;border-top:1.5px solid rgba(0,0,0,.45);transform:rotate(45deg);transform-origin:center;pointer-events:none}.variations_form .variations .label label,.variations_form table.variations th.label label{font-size:var( --chiseikoessw-label-font-size, .875rem );font-weight:var(--chiseikoessw-label-font-weight,600);line-height:1.3;text-transform:var(--chiseikoessw-label-text-transform,none);letter-spacing:var( --chiseikoessw-label-letter-spacing, normal );color:var(--chiseikoessw-label-color,currentColor)}body[class*=chiseikoessw-pdp-align-] .variations_form.cart table.variations td.value,body[class*=chiseikoessw-pdp-align-] .variations_form.cart table.variations th.label{vertical-align:var(--chiseikoessw-pdp-valign,top)}body[class*=chiseikoessw-pdp-align-] .variations_form.cart table.variations th.label{padding-top:var(--chiseikoessw-pdp-label-pad-top,6px)}body.chiseikoessw-pdp-align-middle{--chiseikoessw-pdp-valign:middle}.chiseikoessw-swatch--radio{width:auto;min-width:var(--chiseikoessw-radio-min);height:var(--chiseikoessw-radio-min);padding:var(--chiseikoessw-radio-padding);border-radius:calc(var(--chiseikoessw-radio-min)/ 2);border-color:rgba(15,23,42,.16);background:linear-gradient(180deg,#fff 0,#f6f8fb 100%);font-size:.8125rem;font-weight:500;color:#333;box-shadow:0 1px 2px rgba(15,23,42,.08),inset 0 1px 0 rgba(255,255,255,.92);gap:6px;overflow:visible}.chiseikoessw-swatch__inner--radio{display:inline-flex;align-items:center;gap:6px;width:auto;height:auto;border-radius:0;font-size:inherit;line-height:1}.chiseikoessw-radio-dot{display:inline-block;width:var(--chiseikoessw-radio-dot);height:var(--chiseikoessw-radio-dot);border-radius:50%;border:2px solid #7a828c;background:#fff;flex-shrink:0;transition:border-color .2s,background .2s;box-sizing:border-box}.chiseikoessw-swatch--radio.chiseikoessw-swatch--selected{border-color:var(--chiseikoessw-accent,currentColor);outline:2px solid var(--chiseikoessw-accent,currentColor);outline-offset:2px;background:linear-gradient(180deg,#fff 0,#eef4ff 100%);color:#333;box-shadow:0 1px 2px rgba(15,23,42,.12),inset 0 1px 0 rgba(255,255,255,.92)}.chiseikoessw-swatch--radio.chiseikoessw-selected .chiseikoessw-radio-dot,.chiseikoessw-swatch--radio.chiseikoessw-swatch--selected .chiseikoessw-radio-dot{border-color:var(--chiseikoessw-accent,currentColor);background:var(--chiseikoessw-accent,currentColor)}.chiseikoessw-swatch--radio.chiseikoessw-swatch--loop{width:auto!important;min-width:var(--chiseikoessw-swatch-size-sm)!important;height:var(--chiseikoessw-swatch-size-sm)!important;min-height:var(--chiseikoessw-swatch-size-sm)!important;padding:0 8px;border-radius:calc(var(--chiseikoessw-swatch-size-sm)/ 2);font-size:.6875rem;pointer-events:none;cursor:default}.chiseikoessw-swatch--radio.chiseikoessw-swatch--loop .chiseikoessw-radio-dot{width:10px;height:10px}.chiseikoessw-swatch .screen-reader-text{position:absolute;width:1px;height:1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap}[dir=rtl] .chiseikoessw-card-swatches__row--variable,[dir=rtl] .chiseikoessw-swatches{flex-direction:row-reverse}#chiseikoessw-tooltip{position:fixed;z-index:9999;padding:4px 8px;background:rgba(24,24,24,.92);color:#fff;font-size:.75rem;line-height:1.3;border-radius:6px;box-shadow:0 2px 6px rgba(0,0,0,.18);pointer-events:none;opacity:0;transform:translateY(4px);transition:opacity .18s,transform .18s;white-space:nowrap;max-width:240px}#chiseikoessw-tooltip.is-visible{opacity:1;transform:translateY(0)}body.chiseikoessw-pro-tooltips-active #chiseikoessw-tooltip{display:none!important}@media (prefers-reduced-motion:reduce){.chiseikoessw-swatch,.chiseikoessw-swatch--loop{transition:none;transform:none!important}}@media (forced-colors:active){.chiseikoessw-swatch{border:1px solid ButtonText}.chiseikoessw-swatch--selected{border:1px solid ButtonText;outline:Highlight solid 2px;outline-offset:2px}.chiseikoessw-swatch:focus-visible{outline:Highlight solid 2px;outline-offset:3px}.chiseikoessw-swatch--disabled::after,.chiseikoessw-swatch[aria-disabled=true]::after{border-top-color:CanvasText;border-top-width:2px}}@media print{.chiseikoessw-card-swatches,.chiseikoessw-swatches{display:none}.chiseikoessw-native-select{position:static!important;width:auto!important;height:auto!important;max-width:none!important;max-height:none!important;min-width:auto!important;min-height:auto!important;overflow:visible!important;clip:auto!important;clip-path:none!important;white-space:normal!important;border:1px solid #999!important}}1 :root{--chiseikoessw-swatch-size:32px;--chiseikoessw-swatch-size-sm:32px;--chiseikoessw-swatch-radius:50%;--chiseikoessw-swatch-gap:8px;--chiseikoessw-swatch-gap-sm:6px;--chiseikoessw-text-height:32px;--chiseikoessw-text-min-width:32px;--chiseikoessw-text-padding:0 12px;--chiseikoessw-text-height-sm:32px;--chiseikoessw-text-min-width-sm:32px;--chiseikoessw-text-padding-sm:0 8px;--chiseikoessw-text-font-size:0.75rem;--chiseikoessw-text-font-weight:600;--chiseikoessw-text-white-space:nowrap;--chiseikoessw-linked-justify:flex-start;--chiseikoessw-radio-dot:16px;--chiseikoessw-radio-min:32px;--chiseikoessw-radio-padding:0 14px;--chiseikoessw-swatch-border-width:1px;--chiseikoessw-swatch-border-color:rgba(0, 0, 0, 0.12);--chiseikoessw-transition-speed:0.2s;--chiseikoessw-transition-ease:cubic-bezier(0.22, 0.61, 0.36, 1);--chiseikoessw-swatch-shadow:0 1px 3px rgba(0, 0, 0, .08);--chiseikoessw-swatch-hover-scale:1.08;--chiseikoessw-swatch-hover-z:2;--chiseikoessw-swatch-selected-inset:inset 0 0 0 2px rgba(255, 255, 255, .55);--chiseikoessw-swatch-selected-shadow:0 0 0 2px var(--chiseikoessw-accent, currentColor);--chiseikoessw-swatch-disabled-opacity:0.45}@media (pointer:coarse),(max-width:768px){:root{--chiseikoessw-swatch-size:44px;--chiseikoessw-swatch-size-sm:44px;--chiseikoessw-text-height:48px;--chiseikoessw-text-min-width:48px;--chiseikoessw-text-padding:0 16px;--chiseikoessw-text-height-sm:48px;--chiseikoessw-text-min-width-sm:48px;--chiseikoessw-text-padding-sm:0 12px;--chiseikoessw-radio-dot:20px;--chiseikoessw-radio-min:48px;--chiseikoessw-radio-padding:0 16px}}.chiseikoessw-native-select{position:absolute!important;width:1px!important;height:1px!important;max-width:1px!important;max-height:1px!important;min-width:0!important;min-height:0!important;overflow:hidden!important;clip:rect(0 0 0 0)!important;clip-path:inset(50%)!important;white-space:nowrap!important;border:0!important}.chiseikoessw-swatches{display:flex;flex-wrap:wrap;gap:var(--chiseikoessw-swatch-gap,8px);margin:4px 0;padding:0;list-style:none;contain:layout style}.chiseikoessw-swatch{appearance:none;background:0 0;border:var(--chiseikoessw-swatch-border-width) solid var(--chiseikoessw-swatch-border-color);padding:0;cursor:pointer;display:inline-flex;align-items:center;justify-content:center;flex-shrink:0;box-sizing:border-box;width:var(--chiseikoessw-swatch-size);height:var(--chiseikoessw-swatch-size);border-radius:var(--chiseikoessw-swatch-radius);transition:transform var(--chiseikoessw-transition-speed) var(--chiseikoessw-transition-ease, ease),opacity var(--chiseikoessw-transition-speed) var(--chiseikoessw-transition-ease, ease),box-shadow var(--chiseikoessw-transition-speed) var(--chiseikoessw-transition-ease, ease);box-shadow:var(--chiseikoessw-swatch-shadow);position:relative;overflow:hidden;outline:transparent solid 2px;outline-offset:2px}.chiseikoessw-swatch__inner{display:block;width:100%;height:100%;border-radius:inherit;overflow:hidden;pointer-events:none}.chiseikoessw-swatch--image .chiseikoessw-swatch__inner,.chiseikoessw-swatch--image img{display:block;width:100%;height:100%;object-fit:cover;border-radius:inherit}.chiseikoessw-swatch.chiseikoessw-free-shape-rounded{border-radius:6px}.chiseikoessw-swatch.chiseikoessw-free-shape-square{border-radius:0}.chiseikoessw-swatch[class*=chiseikoessw-free-shape-]:is(.chiseikoessw-swatch--label,.chiseikoessw-swatch--none){width:auto!important;padding:var(--chiseikoessw-text-padding)!important}.chiseikoessw-swatch--loop[class*=chiseikoessw-free-shape-]:is(.chiseikoessw-swatch--label,.chiseikoessw-swatch--none){padding:var(--chiseikoessw-text-padding-sm)!important}.chiseikoessw-swatch--disabled,.chiseikoessw-swatch[aria-disabled=true]{opacity:var(--chiseikoessw-swatch-disabled-opacity);cursor:not-allowed;transform:none!important}.chiseikoessw-swatch--disabled::after,.chiseikoessw-swatch[aria-disabled=true]::after{content:"";position:absolute;top:50%;left:-10%;width:120%;height:0;border-top:1.5px solid rgba(0,0,0,.45);transform:rotate(45deg);transform-origin:center;pointer-events:none}.variations_form .variations .label label,.variations_form table.variations th.label label{font-size:var( --chiseikoessw-label-font-size, .875rem );font-weight:var(--chiseikoessw-label-font-weight,600);line-height:1.3;text-transform:var(--chiseikoessw-label-text-transform,none);letter-spacing:var( --chiseikoessw-label-letter-spacing, normal );color:var(--chiseikoessw-label-color,currentColor)}body[class*=chiseikoessw-pdp-align-] .variations_form.cart table.variations td.value,body[class*=chiseikoessw-pdp-align-] .variations_form.cart table.variations th.label{vertical-align:var(--chiseikoessw-pdp-valign,top)}body[class*=chiseikoessw-pdp-align-] .variations_form.cart table.variations th.label{padding-top:var(--chiseikoessw-pdp-label-pad-top,6px)}body.chiseikoessw-pdp-align-middle{--chiseikoessw-pdp-valign:middle}.chiseikoessw-swatch--radio{width:auto;min-width:var(--chiseikoessw-radio-min);height:var(--chiseikoessw-radio-min);padding:var(--chiseikoessw-radio-padding);border-radius:calc(var(--chiseikoessw-radio-min)/ 2);border-color:rgba(15,23,42,.16);background:linear-gradient(180deg,#fff 0,#f6f8fb 100%);font-size:.8125rem;font-weight:500;color:#333;box-shadow:0 1px 2px rgba(15,23,42,.08),inset 0 1px 0 rgba(255,255,255,.92);gap:6px;overflow:visible}.chiseikoessw-swatch__inner--radio{display:inline-flex;align-items:center;gap:6px;width:auto;height:auto;border-radius:0;font-size:inherit;line-height:1}.chiseikoessw-radio-dot{display:inline-block;width:var(--chiseikoessw-radio-dot);height:var(--chiseikoessw-radio-dot);border-radius:50%;border:2px solid #7a828c;background:#fff;flex-shrink:0;transition:border-color .2s,background .2s;box-sizing:border-box}.chiseikoessw-swatch--radio.chiseikoessw-swatch--selected{border-color:var(--chiseikoessw-accent,currentColor);outline:2px solid var(--chiseikoessw-accent,currentColor);outline-offset:2px;background:linear-gradient(180deg,#fff 0,#eef4ff 100%);color:#333;box-shadow:0 1px 2px rgba(15,23,42,.12),inset 0 1px 0 rgba(255,255,255,.92)}.chiseikoessw-swatch--radio.chiseikoessw-selected .chiseikoessw-radio-dot,.chiseikoessw-swatch--radio.chiseikoessw-swatch--selected .chiseikoessw-radio-dot{border-color:var(--chiseikoessw-accent,currentColor);background:var(--chiseikoessw-accent,currentColor)}.chiseikoessw-swatch--radio.chiseikoessw-swatch--loop{width:auto!important;min-width:var(--chiseikoessw-swatch-size-sm)!important;height:var(--chiseikoessw-swatch-size-sm)!important;min-height:var(--chiseikoessw-swatch-size-sm)!important;padding:0 8px;border-radius:calc(var(--chiseikoessw-swatch-size-sm)/ 2);font-size:.6875rem;pointer-events:none;cursor:default}.chiseikoessw-swatch--radio.chiseikoessw-swatch--loop .chiseikoessw-radio-dot{width:10px;height:10px}.chiseikoessw-swatch .screen-reader-text{position:absolute;width:1px;height:1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap}[dir=rtl] .chiseikoessw-card-swatches__row--variable,[dir=rtl] .chiseikoessw-swatches{flex-direction:row-reverse}#chiseikoessw-tooltip{position:fixed;z-index:9999;padding:4px 8px;background:rgba(24,24,24,.92);color:#fff;font-size:.75rem;line-height:1.3;border-radius:6px;box-shadow:0 2px 6px rgba(0,0,0,.18);pointer-events:none;opacity:0;transform:translateY(4px);transition:opacity .18s,transform .18s;white-space:nowrap;max-width:240px}#chiseikoessw-tooltip.is-visible{opacity:1;transform:translateY(0)}body.chiseikoessw-pro-tooltips-active #chiseikoessw-tooltip{display:none!important}@media (prefers-reduced-motion:reduce){.chiseikoessw-swatch,.chiseikoessw-swatch--loop{transition:none;transform:none!important}}@media (forced-colors:active){.chiseikoessw-swatch{border:1px solid ButtonText}.chiseikoessw-swatch--selected{border:1px solid ButtonText;outline:Highlight solid 2px;outline-offset:2px}.chiseikoessw-swatch:focus-visible{outline:Highlight solid 2px;outline-offset:3px}.chiseikoessw-swatch--disabled::after,.chiseikoessw-swatch[aria-disabled=true]::after{border-top-color:CanvasText;border-top-width:2px}}@media print{.chiseikoessw-card-swatches,.chiseikoessw-swatches{display:none}.chiseikoessw-native-select{position:static!important;width:auto!important;height:auto!important;max-width:none!important;max-height:none!important;min-width:auto!important;min-height:auto!important;overflow:visible!important;clip:auto!important;clip-path:none!important;white-space:normal!important;border:1px solid #999!important}} -
chiseiko-essential-swatches/trunk/assets/js/chiseikoessw-frontend.js
r3598460 r3778841 119 119 || swatches[ 0 ]; 120 120 121 // Write only on change: setting tabindex makes Chromium re-check the 122 // element's focusability, which forces a synchronous style recalc — 123 // rewriting every swatch on every click was the largest plugin-forced 124 // layout cost in the swatch-interaction trace. 121 125 for ( var i = 0; i < swatches.length; i++ ) { 122 swatches[ i ].setAttribute( 'tabindex', swatches[ i ] === target ? '0' : '-1' ); 126 var tabindex = swatches[ i ] === target ? '0' : '-1'; 127 if ( swatches[ i ].getAttribute( 'tabindex' ) !== tabindex ) { 128 swatches[ i ].setAttribute( 'tabindex', tabindex ); 129 } 123 130 } 124 131 } -
chiseiko-essential-swatches/trunk/assets/js/chiseikoessw-frontend.min.js
r3598460 r3778841 1 !function(){"use strict";function e(){document.addEventListener("click",function(e){var t=e.target.closest(".chiseikoessw-swatch");t&&(t.closest(".chiseikoessw-card-swatches")?e.preventDefault():"true"!==t.getAttribute("aria-disabled")?(e.preventDefault(),i(t)):e.preventDefault())}),document.addEventListener("keydown",s),function(){if(!document.querySelector(".chiseikoessw-sr-live-region")){var e=document.createElement("div");e.setAttribute("aria-live","polite"),e.setAttribute("aria-atomic","true"),e.className="chiseikoessw-sr-live-region",e.style.cssText="position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap;border:0;",document.body.appendChild(e)}}(),document.querySelectorAll("form.variations_form").forEach(a),document.querySelectorAll(".chiseikoessw-swatches").forEach(r),function(){if(window.MutationObserver){var e=new MutationObserver(function(e){e.forEach(function(e){e.addedNodes.forEach(function(e){1===e.nodeType&&(e.matches&&e.matches("form.variations_form")&&(a(e),e.querySelectorAll(".chiseikoessw-swatches").forEach(r)),e.querySelectorAll&&e.querySelectorAll("form.variations_form").forEach(function(e){a(e),e.querySelectorAll(".chiseikoessw-swatches").forEach(r)}))})})}),t=document.querySelector(".woocommerce, #content, #main")||document.body;e.observe(t,{childList:!0,subtree:!0})}}()}function t(e,t){e.querySelectorAll(".chiseikoessw-swatch").forEach(function(e){var r=e.dataset.value===t&&""!==t;e.classList.toggle("chiseikoessw-swatch--selected",r),e.setAttribute("aria-checked",r?"true":"false")})}function r(e){if(!e.closest(".chiseikoessw-card-swatches")){var t=Array.from(e.querySelectorAll(".chiseikoessw-swatch"));if(0!==t.length)for(var r=e.querySelector(".chiseikoessw-swatch--selected")||e.querySelector(".chiseikoessw-swatch:not(.chiseikoessw-swatch--disabled)")||t[0],s=0;s<t.length;s++) t[s].setAttribute("tabindex",t[s]===r?"0":"-1")}}function s(e){var t=e.target.closest(".chiseikoessw-swatch");if(t&&!t.closest(".chiseikoessw-card-swatches")){var r="ArrowLeft"===e.key||"Left"===e.key,s="ArrowRight"===e.key||"Right"===e.key,a="Home"===e.key,i="End"===e.key;if(r||s||a||i){e.preventDefault();var o=t.closest(".chiseikoessw-swatches");if(o){var c=Array.from(o.querySelectorAll(".chiseikoessw-swatch:not(.chiseikoessw-swatch--disabled)"));if(0!==c.length){var n=c.indexOf(t),l=c[a?0:i?c.length-1:s?n<c.length-1?n+1:0:n>0?n-1:c.length-1];t.setAttribute("tabindex","-1"),l.setAttribute("tabindex","0"),l.focus()}}}}}function a(e){n(e),function(e){var r=new URLSearchParams(window.location.search),s=!1;e.querySelectorAll(".chiseikoessw-swatches").forEach(function(a){var i=a.dataset.attribute_name;if(i){var o=r.get(i);if(o){var c=a.querySelector('.chiseikoessw-swatch[data-value="'+CSS.escape(o)+'"]');if(c&&"true"!==c.getAttribute("aria-disabled")){t(a,o);var n=e.querySelector('select[name="'+i+'"]');n&&(n.value=o,n.dispatchEvent(new Event("change",{bubbles:!0}))),s=!0}}}}),s&&n(e)}(e);var s=window.CHISEIKOESSW_Utils&&window.CHISEIKOESSW_Utils.WC;s&&(s.onVariationEvent(e,"found_variation.chiseikoessw",u),s.onVariationEvent(e,"reset_data.chiseikoessw",function(){!function(e){t(e,""),n(e),d(e),e.querySelectorAll(".chiseikoessw-swatches").forEach(r),e.querySelectorAll(".chiseikoessw-accordion__selected-value").forEach(function(e){e.textContent="",e.setAttribute("hidden","")})}(e)}),s.onVariationEvent(e,"reload_product_variations.chiseikoessw update_variation_values.chiseikoessw",function(){o.delete(e),c.delete(e),n(e)}))}function i(e){var s=e.closest(".chiseikoessw-swatches");if(s){var a=s.dataset.attribute_name,i=e.dataset.value,o=e.classList.contains("chiseikoessw-swatch--selected")?"":i;t(s,o),r(s);var c=s.getAttribute("aria-label")||"",l=e.getAttribute("aria-label")||e.getAttribute("title")||i;(function(e){var t=document.querySelector(".chiseikoessw-sr-live-region");t&&(t.textContent=e)})(""!==o?c+": "+l+" selected":c+": selection cleared"),setTimeout(function(){""!==o&&function(e){var t=e.dataset.chiseikoesswPreviewSrc;if(t){var r=e.closest("form.variations_form, .product");if(r)h(r,{src:t,srcset:e.dataset.chiseikoesswPreviewSrcset||"",sizes:e.dataset.chiseikoesswPreviewSizes||"",alt:e.dataset.chiseikoesswPreviewAlt||""})}}(e);var r=s.closest("form.variations_form, .product"),i=r&&r.querySelector('select[name="'+a+'"]'),c=[];""!==o&&r&&r.querySelectorAll(".chiseikoessw-swatches").forEach(function(e){if(e!==s){var t=e.dataset.attribute_name,a=r.querySelector('select[name="'+t+'"]');a&&a.value&&c.push({group:e,value:a.value,select:a})}}),i&&(i.value=o,i.dispatchEvent(new Event("change",{bubbles:!0}))),t(s,o);for(var l=0;l<c.length;l++){var u=c[l];t(u.group,u.value),u.select&&!u.select.value&&(u.select.value=u.value)}!function(e){e&&e.querySelectorAll(".chiseikoessw-accordion").forEach(function(e){var t=e.querySelector(".chiseikoessw-accordion__selected-value");if(t){var r=e.querySelector(".chiseikoessw-swatch--selected");if(r){var s=r.getAttribute("aria-label")||r.getAttribute("title")||"";if(s)return t.textContent=s,void t.removeAttribute("hidden")}t.textContent="",t.setAttribute("hidden","")}})}(s.closest("form.variations_form"));var f=s.closest("form.variations_form");f&&n(f),d(s.closest("form.variations_form"))},0)}}"loading"===document.readyState?document.addEventListener("DOMContentLoaded",e):e();var o=new WeakMap,c=new WeakMap;function n(e){var t=function(e){var t=e.dataset.product_variations;if(!t)return null;var r,s=o.get(e);if(s&&s._raw===t)return s;try{r=JSON.parse(t)}catch(e){return null}if(!Array.isArray(r)||0===r.length)return null;for(var a=r[0]&&r[0].attributes?Object.keys(r[0].attributes):[],i=[],c=0;c<r.length;c++){var n=r[c];n.variation_is_active&&n.is_purchasable&&n.is_in_stock&&i.push(n)}var l={variations:r,viableVars:i,attrKeys:a,_raw:t};return o.set(e,l),l}(e);if(t){var s={};e.querySelectorAll('select[name^="attribute_"]').forEach(function(e){s[e.name]=e.value});var a=JSON.stringify(s),n=c.get(e);if(!n||n.key!==a){var u=t.viableVars;e.querySelectorAll(".chiseikoessw-swatches").forEach(function(e){var t=e.dataset.attribute_name;e.querySelectorAll(".chiseikoessw-swatch").forEach(function(e){for(var r=e.dataset.value,a=!1,i=0;i<u.length;i++)if(l(u[i].attributes,s,t,r)){a=!0;break}e.classList.toggle("chiseikoessw-swatch--disabled",!a),e.setAttribute("aria-disabled",a?"false":"true")});var r=Array.from(e.querySelectorAll(".chiseikoessw-swatch:not(.chiseikoessw-swatch--disabled)")),a=e.querySelector(".chiseikoessw-swatch--selected");1!==r.length||a||i(r[0])}),e.querySelectorAll(".chiseikoessw-swatches").forEach(r),c.set(e,{key:a})}}}function l(e,t,r,s){for(var a=Object.keys(t),i=0;i<a.length;i++){var o=a[i],c=e[o]||"";if(""!==c){var n=o===r?s:t[o]||"";if(""!==n&&c!==n)return!1}}return!0}function u(e,t){var r=e.currentTarget;t&&t.image&&t.image.src&&h(r,t.image),n(r)}function h(e,t){var r=e.closest(".product");if(r){var s=r.querySelector(".woocommerce-product-gallery");if(s){var a=window.CHISEIKOESSW_Utils&&window.CHISEIKOESSW_Utils.WC;if(a&&a.hasClassicGalleryManager(s))return;var i=s.querySelector(".woocommerce-product-gallery__image a img, .flex-active-slide img, .woocommerce-product-gallery__image img");if(i)return void f(i,t)}var o=r.querySelector(".wp-block-woocommerce-product-image-gallery, .wc-block-product-image-gallery");if(o){var c=o.querySelector("img");if(c)return void f(c,t)}var n=r.querySelector("img.wp-post-image, img.attachment-woocommerce_thumbnail");n&&f(n,t)}}function f(e,t){t.src&&(e.src=t.src),t.srcset&&(e.srcset=t.srcset),t.sizes&&(e.sizes=t.sizes),t.alt&&(e.alt=t.alt)}function d(e){if(e&&window.history&&window.history.replaceState){var t=new URL(window.location.href),r=t.searchParams;e.querySelectorAll('select[name^="attribute_"]').forEach(function(e){e.value?r.set(e.name,e.value):r.delete(e.name)});var s=t.toString();s!==window.location.href&&window.history.replaceState(null,"",s)}}}();1 !function(){"use strict";function e(){document.addEventListener("click",function(e){var t=e.target.closest(".chiseikoessw-swatch");t&&(t.closest(".chiseikoessw-card-swatches")?e.preventDefault():"true"!==t.getAttribute("aria-disabled")?(e.preventDefault(),i(t)):e.preventDefault())}),document.addEventListener("keydown",s),function(){if(!document.querySelector(".chiseikoessw-sr-live-region")){var e=document.createElement("div");e.setAttribute("aria-live","polite"),e.setAttribute("aria-atomic","true"),e.className="chiseikoessw-sr-live-region",e.style.cssText="position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap;border:0;",document.body.appendChild(e)}}(),document.querySelectorAll("form.variations_form").forEach(a),document.querySelectorAll(".chiseikoessw-swatches").forEach(r),function(){if(window.MutationObserver){var e=new MutationObserver(function(e){e.forEach(function(e){e.addedNodes.forEach(function(e){1===e.nodeType&&(e.matches&&e.matches("form.variations_form")&&(a(e),e.querySelectorAll(".chiseikoessw-swatches").forEach(r)),e.querySelectorAll&&e.querySelectorAll("form.variations_form").forEach(function(e){a(e),e.querySelectorAll(".chiseikoessw-swatches").forEach(r)}))})})}),t=document.querySelector(".woocommerce, #content, #main")||document.body;e.observe(t,{childList:!0,subtree:!0})}}()}function t(e,t){e.querySelectorAll(".chiseikoessw-swatch").forEach(function(e){var r=e.dataset.value===t&&""!==t;e.classList.toggle("chiseikoessw-swatch--selected",r),e.setAttribute("aria-checked",r?"true":"false")})}function r(e){if(!e.closest(".chiseikoessw-card-swatches")){var t=Array.from(e.querySelectorAll(".chiseikoessw-swatch"));if(0!==t.length)for(var r=e.querySelector(".chiseikoessw-swatch--selected")||e.querySelector(".chiseikoessw-swatch:not(.chiseikoessw-swatch--disabled)")||t[0],s=0;s<t.length;s++){var a=t[s]===r?"0":"-1";t[s].getAttribute("tabindex")!==a&&t[s].setAttribute("tabindex",a)}}}function s(e){var t=e.target.closest(".chiseikoessw-swatch");if(t&&!t.closest(".chiseikoessw-card-swatches")){var r="ArrowLeft"===e.key||"Left"===e.key,s="ArrowRight"===e.key||"Right"===e.key,a="Home"===e.key,i="End"===e.key;if(r||s||a||i){e.preventDefault();var o=t.closest(".chiseikoessw-swatches");if(o){var c=Array.from(o.querySelectorAll(".chiseikoessw-swatch:not(.chiseikoessw-swatch--disabled)"));if(0!==c.length){var n=c.indexOf(t),l=c[a?0:i?c.length-1:s?n<c.length-1?n+1:0:n>0?n-1:c.length-1];t.setAttribute("tabindex","-1"),l.setAttribute("tabindex","0"),l.focus()}}}}}function a(e){n(e),function(e){var r=new URLSearchParams(window.location.search),s=!1;e.querySelectorAll(".chiseikoessw-swatches").forEach(function(a){var i=a.dataset.attribute_name;if(i){var o=r.get(i);if(o){var c=a.querySelector('.chiseikoessw-swatch[data-value="'+CSS.escape(o)+'"]');if(c&&"true"!==c.getAttribute("aria-disabled")){t(a,o);var n=e.querySelector('select[name="'+i+'"]');n&&(n.value=o,n.dispatchEvent(new Event("change",{bubbles:!0}))),s=!0}}}}),s&&n(e)}(e);var s=window.CHISEIKOESSW_Utils&&window.CHISEIKOESSW_Utils.WC;s&&(s.onVariationEvent(e,"found_variation.chiseikoessw",u),s.onVariationEvent(e,"reset_data.chiseikoessw",function(){!function(e){t(e,""),n(e),f(e),e.querySelectorAll(".chiseikoessw-swatches").forEach(r),e.querySelectorAll(".chiseikoessw-accordion__selected-value").forEach(function(e){e.textContent="",e.setAttribute("hidden","")})}(e)}),s.onVariationEvent(e,"reload_product_variations.chiseikoessw update_variation_values.chiseikoessw",function(){o.delete(e),c.delete(e),n(e)}))}function i(e){var s=e.closest(".chiseikoessw-swatches");if(s){var a=s.dataset.attribute_name,i=e.dataset.value,o=e.classList.contains("chiseikoessw-swatch--selected")?"":i;t(s,o),r(s);var c=s.getAttribute("aria-label")||"",l=e.getAttribute("aria-label")||e.getAttribute("title")||i;(function(e){var t=document.querySelector(".chiseikoessw-sr-live-region");t&&(t.textContent=e)})(""!==o?c+": "+l+" selected":c+": selection cleared"),setTimeout(function(){""!==o&&function(e){var t=e.dataset.chiseikoesswPreviewSrc;if(t){var r=e.closest("form.variations_form, .product");if(r)h(r,{src:t,srcset:e.dataset.chiseikoesswPreviewSrcset||"",sizes:e.dataset.chiseikoesswPreviewSizes||"",alt:e.dataset.chiseikoesswPreviewAlt||""})}}(e);var r=s.closest("form.variations_form, .product"),i=r&&r.querySelector('select[name="'+a+'"]'),c=[];""!==o&&r&&r.querySelectorAll(".chiseikoessw-swatches").forEach(function(e){if(e!==s){var t=e.dataset.attribute_name,a=r.querySelector('select[name="'+t+'"]');a&&a.value&&c.push({group:e,value:a.value,select:a})}}),i&&(i.value=o,i.dispatchEvent(new Event("change",{bubbles:!0}))),t(s,o);for(var l=0;l<c.length;l++){var u=c[l];t(u.group,u.value),u.select&&!u.select.value&&(u.select.value=u.value)}!function(e){e&&e.querySelectorAll(".chiseikoessw-accordion").forEach(function(e){var t=e.querySelector(".chiseikoessw-accordion__selected-value");if(t){var r=e.querySelector(".chiseikoessw-swatch--selected");if(r){var s=r.getAttribute("aria-label")||r.getAttribute("title")||"";if(s)return t.textContent=s,void t.removeAttribute("hidden")}t.textContent="",t.setAttribute("hidden","")}})}(s.closest("form.variations_form"));var d=s.closest("form.variations_form");d&&n(d),f(s.closest("form.variations_form"))},0)}}"loading"===document.readyState?document.addEventListener("DOMContentLoaded",e):e();var o=new WeakMap,c=new WeakMap;function n(e){var t=function(e){var t=e.dataset.product_variations;if(!t)return null;var r,s=o.get(e);if(s&&s._raw===t)return s;try{r=JSON.parse(t)}catch(e){return null}if(!Array.isArray(r)||0===r.length)return null;for(var a=r[0]&&r[0].attributes?Object.keys(r[0].attributes):[],i=[],c=0;c<r.length;c++){var n=r[c];n.variation_is_active&&n.is_purchasable&&n.is_in_stock&&i.push(n)}var l={variations:r,viableVars:i,attrKeys:a,_raw:t};return o.set(e,l),l}(e);if(t){var s={};e.querySelectorAll('select[name^="attribute_"]').forEach(function(e){s[e.name]=e.value});var a=JSON.stringify(s),n=c.get(e);if(!n||n.key!==a){var u=t.viableVars;e.querySelectorAll(".chiseikoessw-swatches").forEach(function(e){var t=e.dataset.attribute_name;e.querySelectorAll(".chiseikoessw-swatch").forEach(function(e){for(var r=e.dataset.value,a=!1,i=0;i<u.length;i++)if(l(u[i].attributes,s,t,r)){a=!0;break}e.classList.toggle("chiseikoessw-swatch--disabled",!a),e.setAttribute("aria-disabled",a?"false":"true")});var r=Array.from(e.querySelectorAll(".chiseikoessw-swatch:not(.chiseikoessw-swatch--disabled)")),a=e.querySelector(".chiseikoessw-swatch--selected");1!==r.length||a||i(r[0])}),e.querySelectorAll(".chiseikoessw-swatches").forEach(r),c.set(e,{key:a})}}}function l(e,t,r,s){for(var a=Object.keys(t),i=0;i<a.length;i++){var o=a[i],c=e[o]||"";if(""!==c){var n=o===r?s:t[o]||"";if(""!==n&&c!==n)return!1}}return!0}function u(e,t){var r=e.currentTarget;t&&t.image&&t.image.src&&h(r,t.image),n(r)}function h(e,t){var r=e.closest(".product");if(r){var s=r.querySelector(".woocommerce-product-gallery");if(s){var a=window.CHISEIKOESSW_Utils&&window.CHISEIKOESSW_Utils.WC;if(a&&a.hasClassicGalleryManager(s))return;var i=s.querySelector(".woocommerce-product-gallery__image a img, .flex-active-slide img, .woocommerce-product-gallery__image img");if(i)return void d(i,t)}var o=r.querySelector(".wp-block-woocommerce-product-image-gallery, .wc-block-product-image-gallery");if(o){var c=o.querySelector("img");if(c)return void d(c,t)}var n=r.querySelector("img.wp-post-image, img.attachment-woocommerce_thumbnail");n&&d(n,t)}}function d(e,t){t.src&&(e.src=t.src),t.srcset&&(e.srcset=t.srcset),t.sizes&&(e.sizes=t.sizes),t.alt&&(e.alt=t.alt)}function f(e){if(e&&window.history&&window.history.replaceState){var t=new URL(window.location.href),r=t.searchParams;e.querySelectorAll('select[name^="attribute_"]').forEach(function(e){e.value?r.set(e.name,e.value):r.delete(e.name)});var s=t.toString();s!==window.location.href&&window.history.replaceState(null,"",s)}}}(); -
chiseiko-essential-swatches/trunk/assets/js/chiseikoessw-utils.js
r3598460 r3778841 479 479 $gallery.off( 'click', '.woocommerce-product-gallery__image a' ); 480 480 481 $gallery.wc_product_gallery(); 482 return true; 481 // Unbind the handlers the PREVIOUS re-init added (see 482 // REINIT_STACKED_EVENTS), then record the ones this init adds. 483 var previous = galleryReinitHandlers ? galleryReinitHandlers.get( gallery ) : null; 484 if ( previous ) { 485 for ( var p = 0; p < previous.jquery.length; p++ ) { 486 global.jQuery( previous.jquery[ p ].target ).off( previous.jquery[ p ].type, previous.jquery[ p ].handler ); 487 } 488 for ( var n = 0; n < previous.native.length; n++ ) { 489 previous.native[ n ].target.removeEventListener( previous.native[ n ].type, previous.native[ n ].listener, previous.native[ n ].options ); 490 } 491 } 492 var before = snapshotReinitHandlers( gallery ); 493 494 var native = captureNativeListeners( gallery, function () { 495 $gallery.wc_product_gallery(); 496 } ); 497 498 if ( galleryReinitHandlers ) { 499 galleryReinitHandlers.set( gallery, { 500 jquery: diffReinitHandlers( before, snapshotReinitHandlers( gallery ) ), 501 native: native, 502 } ); 503 } 504 return true; 505 } 506 507 /** 508 * Events `wc_product_gallery()` binds on EVERY init and never unbinds: 509 * - Flexslider: window `resize`/`orientationchange`/`focus` (resize logic) 510 * and document `keyup` (keyboard nav); 511 * - WooCommerce's ProductGallery constructor: `woocommerce_gallery_init_zoom` 512 * and `woocommerce_gallery_reset_slide_position` on the gallery element. 513 * Flexslider also adds ANONYMOUS native listeners — document 514 * `visibilitychange` (`pauseInvisible`, on by default) and, on touch 515 * devices, `touchstart`/`touchmove` on the gallery element — 516 * which are captured during the synchronous init (captureNativeListeners). 517 * Each re-init therefore stacked another set. Every stacked handler kept its 518 * old slider / ProductGallery — and through `$images` the detached slides — 519 * alive (≈35 DOM nodes and ≈20 listeners per variation gallery swap), and 520 * every stacked init-zoom handler re-ran zoom setup on each zoom refresh. 521 */ 522 var REINIT_STACKED_EVENTS = [ 523 [ 'window', 'resize' ], 524 [ 'window', 'orientationchange' ], 525 [ 'window', 'focus' ], 526 [ 'document', 'keyup' ], 527 [ 'gallery', 'woocommerce_gallery_init_zoom' ], 528 [ 'gallery', 'woocommerce_gallery_reset_slide_position' ], 529 ]; 530 531 /** gallery element → handlers its last re-init added (see above). */ 532 var galleryReinitHandlers = typeof WeakMap === 'function' ? new WeakMap() : null; 533 534 /** 535 * Lists the jQuery handlers currently bound for REINIT_STACKED_EVENTS. 536 * 537 * @param {Element} gallery The `.woocommerce-product-gallery` element. 538 * @returns {Array<{target: Object, type: string, handler: Function}>} 539 */ 540 function snapshotReinitHandlers( gallery ) { 541 var out = []; 542 var $ = global.jQuery; 543 if ( ! $ || typeof $._data !== 'function' ) return out; 544 var targets = { window: global, document: global.document, gallery: gallery }; 545 for ( var i = 0; i < REINIT_STACKED_EVENTS.length; i++ ) { 546 var target = targets[ REINIT_STACKED_EVENTS[ i ][ 0 ] ]; 547 var type = REINIT_STACKED_EVENTS[ i ][ 1 ]; 548 var events = target ? $._data( target, 'events' ) : null; 549 var list = events && events[ type ] ? events[ type ] : []; 550 for ( var j = 0; j < list.length; j++ ) { 551 out.push( { target: target, type: type, handler: list[ j ].handler } ); 552 } 553 } 554 return out; 555 } 556 557 /** 558 * Runs `fn` while recording the anonymous native listeners Flexslider adds 559 * on every init (document `visibilitychange`; gallery `touchstart` / 560 * `touchmove`), so they can be removed later. Only those event types on 561 * those targets are recorded: a listener a third party binds during the 562 * init (e.g. from a `wc-product-gallery-after-init` callback) for any other 563 * event or target is kept. jQuery's shared per-element dispatcher is 564 * excluded: removing it would silence every jQuery handler of that type, 565 * and jQuery-bound handlers are tracked separately (snapshotReinitHandlers). 566 * 567 * @param {Element} gallery The `.woocommerce-product-gallery` element. 568 * @param {Function} fn 569 * @returns {Array<{target: EventTarget, type: string, listener: *, options: *}>} 570 */ 571 function captureNativeListeners( gallery, fn ) { 572 var proto = global.EventTarget && global.EventTarget.prototype; 573 if ( ! proto ) { 574 fn(); 575 return []; 576 } 577 var original = proto.addEventListener; 578 var captured = []; 579 proto.addEventListener = function ( type, listener, options ) { 580 if ( ( this === global.document && 'visibilitychange' === type ) || ( this === gallery && /^touch(start|move)$/.test( type ) ) ) { 581 captured.push( { target: this, type: type, listener: listener, options: options } ); 582 } 583 return original.apply( this, arguments ); 584 }; 585 try { 586 fn(); 587 } finally { 588 proto.addEventListener = original; 589 } 590 var $ = global.jQuery; 591 return captured.filter( function ( c ) { 592 var data = $ && typeof $._data === 'function' ? $._data( c.target ) : null; 593 return ! data || c.listener !== data.handle; 594 } ); 595 } 596 597 /** 598 * Returns the entries of `after` that were not present in `before`. 599 * 600 * @param {Array} before 601 * @param {Array} after 602 * @returns {Array} 603 */ 604 function diffReinitHandlers( before, after ) { 605 return after.filter( function ( a ) { 606 return ! before.some( function ( b ) { 607 return b.target === a.target && b.type === a.type && b.handler === a.handler; 608 } ); 609 } ); 483 610 } 484 611 -
chiseiko-essential-swatches/trunk/assets/js/chiseikoessw-utils.min.js
r3598460 r3778841 1 !function(e){"use strict";var r=new Set(["SCRIPT","IFRAME","OBJECT","EMBED","FORM","STYLE","LINK","SVG","MATH","TEMPLATE","BASE","APPLET","META","NOSCRIPT"]);function t(e){for(var o=e.firstChild;o;){var n=o.nextSibling;if(1===o.nodeType)if(r.has(o.tagName))e.removeChild(o);else{for(var c=o.attributes,i=c.length-1;i>=0;i--){var a=c[i].name.toLowerCase();0!==a.indexOf("on")&&"srcdoc"!==a&&"formaction"!==a||o.removeAttribute(c[i].name)}["href","src","action"].forEach(function(e){var r=o.getAttribute(e);r&&/^\s*javascript\s*:/i.test(r)&&o.removeAttribute(e)}),t(o)}o=n}}var o=[".related",".up-sells",".upsells",".cross-sells",".products",".woocommerce-grouped-product-list",".wc-block-product",".wc-block-grid",".wc-block-grid__product",".wc-block-grid__products",".wc-block-product-template",".wp-block-post-template",".wc-block-featured-products",".wc-block-handpicked-products",".wc-block-related-products",".wc-block-all-products",".wp-block-woocommerce-related-products",".wp-block-woocommerce-cross-sells",".wp-block-woocommerce-up-sells","#chiseikoessw-pro-sticky-bar",".chiseikoessw-linked-swatches",".chiseikoessw-card-swatches"].join(",");e.CHISEIKOESSW_Utils={debounce:function(e,r){var t;return function(){var o=this,n=arguments;clearTimeout(t),t=setTimeout(function(){e.apply(o,n)},r)}},throttle:function(e,r){var t=0;return function(){var o=Date.now();o-t>=r&&(t=o,e.apply(this,arguments))}},hasAnyInStock:function(e,r,t){return Object.values(e).some(function(e){var o=e.attributes||{};return(o[r]===t||""===o[r])&&e.is_in_stock})},hasAnyInStockFiltered:function(e,r,t,o){return Object.values(e).some(function(e){var n=e.attributes||{};if(n[r]!==t&&""!==n[r])return!1;for(var c in o)if(c!==r&&""!==n[c]&&n[c]!==o[c])return!1;return e.is_in_stock})},swapCardImage:function(e,r,t,o){var n=t(e);if(n&&r.image){var c=r.image;if(c.src){e.classList.add(o);var i=new Image;i.onload=function(){n.src=c.src,n.srcset=c.srcset||"",e.classList.remove(o)},i.onerror=function(){e.classList.remove(o)},i.src=c.src}}},applyRoving:function(e,r,t,o){var n=Array.from(e.querySelectorAll(r));if(0!==n.length)for(var c=e.querySelector("."+t)||e.querySelector(r+":not(."+o+")")||n[0],i=0;i<n.length;i++)n[i].setAttribute("tabindex",n[i]===c?"0":"-1")},handleRovingKeydown:function(e,r,t,o){var n=e.target.closest(r);if(!n)return!1;var c="ArrowLeft"===e.key||"Left"===e.key,i="ArrowRight"===e.key||"Right"===e.key,a="Home"===e.key,u="End"===e.key;if(!(c||i||a||u))return!1;var s=n.closest(t);if(!s)return!1;var l=Array.from(s.querySelectorAll(r+":not(."+o+")"));if(0===l.length)return!1;var f,d=l.indexOf(n);return f=a?0:u?l.length-1:i?d<l.length-1?d+1:0:d>0?d-1:l.length-1,n.setAttribute("tabindex","-1"),l[f].setAttribute("tabindex","0"),l[f].focus(),!0},sanitizePriceHtml:function(e){var r=document.createRange().createContextualFragment(e);return t(r),r},PDP:{EXCLUDE_PRODUCT_CONTAINERS:o,resolveMainEl:function(r,t){for(var n=(t||e.document).querySelectorAll(r),c=0;c<n.length;c++)if(!n[c].closest(o))return n[c];return null},isSwapActive:function(){var r=e.document&&e.document.documentElement;return!!(r&&r.classList&&r.classList.contains("chiseikoessw-swap-loading"))},onMemberSwap:function r(t){return!(!e.document||"function"!=typeof t||(r._bound||(r._bound=[]),-1!==r._bound.indexOf(t)||(r._bound.push(t),e.document.addEventListener("chiseikoessw:linked:selected",t)),0))}},WC:{isAvailable:function(){return!!e.jQuery},onVariationEvent:function(r,t,o){return!!e.jQuery&&(e.jQuery(r).on(t,o),!0)},hasClassicGalleryManager:function(r){return!(!e.jQuery||!r||!e.jQuery(r).data("product_gallery"))},applyCartFragments:function(r,t,o){if(!e.jQuery||!r)return!1;if(e.jQuery.each(r,function(r,t){e.jQuery(r).replaceWith(t)}),t)try{sessionStorage.setItem("wc_cart_hash",t)}catch(e){}return e.jQuery(document.body).trigger("added_to_cart",[r,t,o]),!0},setJqueryData:function(r,t,o){return!(!e.jQuery||!r||(e.jQuery(r).data(t,o),0))},clearClassicGalleryManager:function(r){if(!e.jQuery||!r)return!1;var t=e.jQuery(r);return t.data("flexslider")&&t.removeData("flexslider"),t.removeData("product_gallery"),!0},reinitClassicGallery:function(r){if(!e.jQuery||!r)return!1;var t=e.jQuery(r);return"function"==typeof t.wc_product_gallery&&(t.off("click",".woocommerce-product-gallery__trigger"),t.off("keydown",".woocommerce-product-gallery__trigger"),t.off("click",".woocommerce-product-gallery__image a"),t.wc_product_gallery(),!0)},refreshGalleryZoom:function(r){return!(!e.jQuery||!r||(e.jQuery(r).trigger("woocommerce_gallery_init_zoom"),0))},reinitProductTabs:function(r){if(!e.jQuery)return!1;var t=(r||e.document).querySelectorAll(".wc-tabs-wrapper, .woocommerce-tabs, #rating");return!!t.length&&(e.jQuery(t).trigger("init"),!0)},triggerZoomDestroy:function(r){if(!e.jQuery||!r)return!1;var t=e.jQuery(r);if(!t.length)return!1;try{t.trigger("zoom.destroy")}catch(e){}return!0},offZoomEvents:function(r){if(!e.jQuery||!r)return!1;var t=e.jQuery(r);return!!t.length&&(t.off("mouseenter.zoom mousemove.zoom mouseleave.zoom"),!0)},onZoomDestroy:function(r,t,o){if(!e.jQuery||!r)return!1;var n="zoom.destroy."+t;return e.jQuery(r).off(n).on(n,o),!0},reinitVariationForm:function(r,t){if(!e.jQuery||!r)return!1;var o=e.jQuery(r);return o.data("product_variations",t),o.find('select[name^="attribute_"]').val("").trigger("change"),o.find("input.variation_id").val("").trigger("change"),"function"==typeof o.wc_variation_form?o.wc_variation_form():o.trigger("check_variations"),!0}}}}(window);1 !function(e){"use strict";var r=new Set(["SCRIPT","IFRAME","OBJECT","EMBED","FORM","STYLE","LINK","SVG","MATH","TEMPLATE","BASE","APPLET","META","NOSCRIPT"]);function t(e){for(var n=e.firstChild;n;){var o=n.nextSibling;if(1===n.nodeType)if(r.has(n.tagName))e.removeChild(n);else{for(var i=n.attributes,a=i.length-1;a>=0;a--){var u=i[a].name.toLowerCase();0!==u.indexOf("on")&&"srcdoc"!==u&&"formaction"!==u||n.removeAttribute(i[a].name)}["href","src","action"].forEach(function(e){var r=n.getAttribute(e);r&&/^\s*javascript\s*:/i.test(r)&&n.removeAttribute(e)}),t(n)}n=o}}var n=[["window","resize"],["window","orientationchange"],["window","focus"],["document","keyup"],["gallery","woocommerce_gallery_init_zoom"],["gallery","woocommerce_gallery_reset_slide_position"]],o="function"==typeof WeakMap?new WeakMap:null;function i(r){var t=[],o=e.jQuery;if(!o||"function"!=typeof o._data)return t;for(var i={window:e,document:e.document,gallery:r},a=0;a<n.length;a++)for(var u=i[n[a][0]],c=n[a][1],s=u?o._data(u,"events"):null,l=s&&s[c]?s[c]:[],f=0;f<l.length;f++)t.push({target:u,type:c,handler:l[f].handler});return t}function a(e,r){return r.filter(function(r){return!e.some(function(e){return e.target===r.target&&e.type===r.type&&e.handler===r.handler})})}var u=[".related",".up-sells",".upsells",".cross-sells",".products",".woocommerce-grouped-product-list",".wc-block-product",".wc-block-grid",".wc-block-grid__product",".wc-block-grid__products",".wc-block-product-template",".wp-block-post-template",".wc-block-featured-products",".wc-block-handpicked-products",".wc-block-related-products",".wc-block-all-products",".wp-block-woocommerce-related-products",".wp-block-woocommerce-cross-sells",".wp-block-woocommerce-up-sells","#chiseikoessw-pro-sticky-bar",".chiseikoessw-linked-swatches",".chiseikoessw-card-swatches"].join(",");e.CHISEIKOESSW_Utils={debounce:function(e,r){var t;return function(){var n=this,o=arguments;clearTimeout(t),t=setTimeout(function(){e.apply(n,o)},r)}},throttle:function(e,r){var t=0;return function(){var n=Date.now();n-t>=r&&(t=n,e.apply(this,arguments))}},hasAnyInStock:function(e,r,t){return Object.values(e).some(function(e){var n=e.attributes||{};return(n[r]===t||""===n[r])&&e.is_in_stock})},hasAnyInStockFiltered:function(e,r,t,n){return Object.values(e).some(function(e){var o=e.attributes||{};if(o[r]!==t&&""!==o[r])return!1;for(var i in n)if(i!==r&&""!==o[i]&&o[i]!==n[i])return!1;return e.is_in_stock})},swapCardImage:function(e,r,t,n){var o=t(e);if(o&&r.image){var i=r.image;if(i.src){e.classList.add(n);var a=new Image;a.onload=function(){o.src=i.src,o.srcset=i.srcset||"",e.classList.remove(n)},a.onerror=function(){e.classList.remove(n)},a.src=i.src}}},applyRoving:function(e,r,t,n){var o=Array.from(e.querySelectorAll(r));if(0!==o.length)for(var i=e.querySelector("."+t)||e.querySelector(r+":not(."+n+")")||o[0],a=0;a<o.length;a++)o[a].setAttribute("tabindex",o[a]===i?"0":"-1")},handleRovingKeydown:function(e,r,t,n){var o=e.target.closest(r);if(!o)return!1;var i="ArrowLeft"===e.key||"Left"===e.key,a="ArrowRight"===e.key||"Right"===e.key,u="Home"===e.key,c="End"===e.key;if(!(i||a||u||c))return!1;var s=o.closest(t);if(!s)return!1;var l=Array.from(s.querySelectorAll(r+":not(."+n+")"));if(0===l.length)return!1;var f,d=l.indexOf(o);return f=u?0:c?l.length-1:a?d<l.length-1?d+1:0:d>0?d-1:l.length-1,o.setAttribute("tabindex","-1"),l[f].setAttribute("tabindex","0"),l[f].focus(),!0},sanitizePriceHtml:function(e){var r=document.createRange().createContextualFragment(e);return t(r),r},PDP:{EXCLUDE_PRODUCT_CONTAINERS:u,resolveMainEl:function(r,t){for(var n=(t||e.document).querySelectorAll(r),o=0;o<n.length;o++)if(!n[o].closest(u))return n[o];return null},isSwapActive:function(){var r=e.document&&e.document.documentElement;return!!(r&&r.classList&&r.classList.contains("chiseikoessw-swap-loading"))},onMemberSwap:function r(t){return!(!e.document||"function"!=typeof t||(r._bound||(r._bound=[]),-1!==r._bound.indexOf(t)||(r._bound.push(t),e.document.addEventListener("chiseikoessw:linked:selected",t)),0))}},WC:{isAvailable:function(){return!!e.jQuery},onVariationEvent:function(r,t,n){return!!e.jQuery&&(e.jQuery(r).on(t,n),!0)},hasClassicGalleryManager:function(r){return!(!e.jQuery||!r||!e.jQuery(r).data("product_gallery"))},applyCartFragments:function(r,t,n){if(!e.jQuery||!r)return!1;if(e.jQuery.each(r,function(r,t){e.jQuery(r).replaceWith(t)}),t)try{sessionStorage.setItem("wc_cart_hash",t)}catch(e){}return e.jQuery(document.body).trigger("added_to_cart",[r,t,n]),!0},setJqueryData:function(r,t,n){return!(!e.jQuery||!r||(e.jQuery(r).data(t,n),0))},clearClassicGalleryManager:function(r){if(!e.jQuery||!r)return!1;var t=e.jQuery(r);return t.data("flexslider")&&t.removeData("flexslider"),t.removeData("product_gallery"),!0},reinitClassicGallery:function(r){if(!e.jQuery||!r)return!1;var t=e.jQuery(r);if("function"!=typeof t.wc_product_gallery)return!1;t.off("click",".woocommerce-product-gallery__trigger"),t.off("keydown",".woocommerce-product-gallery__trigger"),t.off("click",".woocommerce-product-gallery__image a");var n=o?o.get(r):null;if(n){for(var u=0;u<n.jquery.length;u++)e.jQuery(n.jquery[u].target).off(n.jquery[u].type,n.jquery[u].handler);for(var c=0;c<n.native.length;c++)n.native[c].target.removeEventListener(n.native[c].type,n.native[c].listener,n.native[c].options)}var s=i(r),l=function(r,t){var n=e.EventTarget&&e.EventTarget.prototype;if(!n)return t(),[];var o=n.addEventListener,i=[];n.addEventListener=function(t,n,a){return(this===e.document&&"visibilitychange"===t||this===r&&/^touch(start|move)$/.test(t))&&i.push({target:this,type:t,listener:n,options:a}),o.apply(this,arguments)};try{t()}finally{n.addEventListener=o}var a=e.jQuery;return i.filter(function(e){var r=a&&"function"==typeof a._data?a._data(e.target):null;return!r||e.listener!==r.handle})}(r,function(){t.wc_product_gallery()});return o&&o.set(r,{jquery:a(s,i(r)),native:l}),!0},refreshGalleryZoom:function(r){return!(!e.jQuery||!r||(e.jQuery(r).trigger("woocommerce_gallery_init_zoom"),0))},reinitProductTabs:function(r){if(!e.jQuery)return!1;var t=(r||e.document).querySelectorAll(".wc-tabs-wrapper, .woocommerce-tabs, #rating");return!!t.length&&(e.jQuery(t).trigger("init"),!0)},triggerZoomDestroy:function(r){if(!e.jQuery||!r)return!1;var t=e.jQuery(r);if(!t.length)return!1;try{t.trigger("zoom.destroy")}catch(e){}return!0},offZoomEvents:function(r){if(!e.jQuery||!r)return!1;var t=e.jQuery(r);return!!t.length&&(t.off("mouseenter.zoom mousemove.zoom mouseleave.zoom"),!0)},onZoomDestroy:function(r,t,n){if(!e.jQuery||!r)return!1;var o="zoom.destroy."+t;return e.jQuery(r).off(o).on(o,n),!0},reinitVariationForm:function(r,t){if(!e.jQuery||!r)return!1;var n=e.jQuery(r);return n.data("product_variations",t),n.find('select[name^="attribute_"]').val("").trigger("change"),n.find("input.variation_id").val("").trigger("change"),"function"==typeof n.wc_variation_form?n.wc_variation_form():n.trigger("check_variations"),!0}}}}(window); -
chiseiko-essential-swatches/trunk/chiseiko-essential-swatches.php
r3598460 r3778841 4 4 * Plugin URI: https://chiseikotech.com/chiseiko-essential-swatches/ 5 5 * Description: Turn WooCommerce variation dropdowns into clickable color, image, text, and button swatches on product and shop pages. 6 * Version: 1. 0.06 * Version: 1.1.0 7 7 * Author: Chiseiko LLC 8 8 * Author URI: https://chiseikotech.com … … 15 15 * Requires Plugins: woocommerce 16 16 * WC requires at least: 8.0 17 * WC tested up to: 1 0.517 * WC tested up to: 11.2.1 18 18 * 19 19 * @package ChiseikoEssentialSwatches … … 29 29 // ── Plugin constants ────────────────────────────────────────────────────────── 30 30 31 define( 'CHISEIKOESSW_VERSION', '1. 0.0' );31 define( 'CHISEIKOESSW_VERSION', '1.1.0' ); 32 32 define( 'CHISEIKOESSW_PLUGIN_DIR', plugin_dir_path( __FILE__ ) ); 33 33 define( 'CHISEIKOESSW_PLUGIN_URL', plugin_dir_url( __FILE__ ) ); … … 130 130 new CHISEIKOESSW_Settings(); 131 131 new CHISEIKOESSW_User_Guide(); 132 new CHISEIKOESSW_Plugin_Links(); 133 // Getting-started notice for stores with no swatches configured yet. 134 // The review notice stays silent while this one is showing. 135 new CHISEIKOESSW_Onboarding_Notice(); 136 new CHISEIKOESSW_Review_Notice(); 137 // Attribute-wide default swatch type (Products → Attributes). 138 new CHISEIKOESSW_Attribute_Defaults(); 132 139 } 133 140 134 141 new CHISEIKOESSW_Frontend(); 142 143 // Global swatch shape/size (inline CSS tokens). Self-disables at the 144 // default values and when Pro's Advanced Styling owns appearance. 145 new CHISEIKOESSW_Appearance(); 135 146 136 147 // Batch variation-data AJAX endpoint (used by chiseikoessw-utils.js CHISEIKOESSW_Batch). -
chiseiko-essential-swatches/trunk/docs/chapters.json
r3598460 r3778841 3 3 "slug": "installation", 4 4 "title": "Installation", 5 "num": 1, 5 6 "edition": "free" 6 7 }, … … 8 9 "slug": "creating-attributes", 9 10 "title": "Creating Attributes & Swatches", 11 "num": 2, 10 12 "edition": "free" 11 13 }, … … 13 15 "slug": "variable-products", 14 16 "title": "Setting Up Variable Products", 17 "num": 3, 15 18 "edition": "free" 16 19 }, … … 18 21 "slug": "settings", 19 22 "title": "Chiseiko Essential Swatches Settings", 23 "num": 4, 24 "edition": "free" 25 }, 26 { 27 "slug": "customizing-swatches", 28 "title": "Customizing Swatches", 29 "num": 25, 20 30 "edition": "free" 21 31 } -
chiseiko-essential-swatches/trunk/docs/creating-attributes.html
r3598460 r3778841 169 169 <p>That is perfectly fine! If you leave <strong>Swatch Type</strong> set to "— Select type —", the term will still appear as a button on your product pages — it just shows the term's name as a text label (called a <strong>text pill</strong>). This is useful for "Size" attributes where colors don't make sense.</p> 170 170 <hr> 171 <h2 id="set-a-default-swatch-type-for-a-whole-attribute">Set a Default Swatch Type for a Whole Attribute</h2> 172 <p>For attributes like "Size" or "Material", where every term should look the same, you don't have to edit each term. Set the type once for the whole attribute instead:</p> 173 <ol> 174 <li>Go to <strong>Products → Attributes</strong> and click <strong>Edit</strong> under the attribute name (or fill in the form to add a new attribute).</li> 175 <li>In <strong>Default swatch type</strong>, choose <strong>Label buttons</strong> or <strong>Radio buttons</strong>.</li> 176 <li>Click <strong>Update</strong> (or <strong>Add attribute</strong>).</li> 177 </ol> 178 <p>Every term of that attribute now shows as a label (or radio) swatch on your product pages, including terms you add later. A term that has its <strong>own</strong> Swatch Type set keeps it — the default only fills in for terms left on "— Select type —". To go back, choose <strong>None (set per term)</strong> and update the attribute.</p> 179 <blockquote> 180 <p><strong>Why only labels and radio buttons?</strong> Color and image swatches need a color or picture for each term, so those are always set per term (Steps 4–5 above).</p> 181 </blockquote> 182 <hr> 171 183 <h2 id="the-swatch-preview-column">The Swatch Preview Column</h2> 172 184 <p>On the Terms list screen, notice the <strong>Swatch</strong> column. It shows:</p> … … 188 200 <li>The <strong>Swatch Tooltips</strong> module — add <strong>hover tooltips</strong> that show the color name when a customer mouses over a swatch</li> 189 201 </ul> 190 <p>These are configured per-term on the same edit screens you just used. See <a href="{{CH:advanced-styling}}">Chapter 9 — Advanced Styling</a>for step-by-step instructions.</p>191 <hr> 202 <p>These are configured per-term on the same edit screens you just used. See Chapter 9 — Advanced Styling in the Pro user guide for step-by-step instructions.</p> 203 <hr> -
chiseiko-essential-swatches/trunk/docs/installation.html
r3598460 r3778841 16 16 <h3 id="step-2--activate-the-plugin">Step 2 — Activate the plugin</h3> 17 17 <p>After installation, click <strong>Activate Plugin</strong>.</p> 18 <p>You should now see <strong>"Chiseiko Essential Swatches"</strong> listed in your <strong>Plugins</strong> screen with a green "Active" badge.</p> 18 <p>You should now see <strong>"Chiseiko Essential Swatches"</strong> listed in your <strong>Plugins</strong> screen with a green "Active" badge. Under its name are two shortcuts: <strong>Settings</strong> opens the plugin's settings tab and <strong>Guide</strong> opens this user guide.</p> 19 <p>Until you have set up your first swatch, a <strong>getting-started notice</strong> appears at the top of the Plugins screen, the <strong>Products → Attributes</strong> screen, and the plugin's settings tab. Its buttons take you straight to the attributes screen, this guide, and the display settings. It disappears on its own once any attribute term has a swatch type (or an attribute has a default swatch type), and you can also dismiss it permanently with <strong>Dismiss</strong> or the <strong>×</strong>.</p> 20 <p>Once the plugin has been working for a while — 3 days after installation if at least one swatch is set up, or 14 days otherwise — store managers see a short <strong>review request</strong> on the plugin's own screens — Plugins, <strong>Products → Attributes</strong> and its term screens, the plugin's settings tab, and the guide — never elsewhere in wp-admin. <strong>Leave a review</strong> opens the review page and hides the request for good; <strong>I already did</strong> hides it for good too; <strong>Maybe later</strong> or the <strong>×</strong> hides it for 30 days. With Chiseiko Essential Swatches Pro installed, the request asks for a review of Pro on chiseikotech.com instead of WordPress.org. Each store manager's choice is remembered for their own account.</p> 19 21 <blockquote> 20 22 <p><strong>Tip:</strong> If you see a red notice saying WooCommerce is missing or needs to be updated, make sure WooCommerce is installed and active first, then refresh the page.</p> … … 46 48 <hr> 47 49 <h2 id="what-gets-installed">What Gets Installed</h2> 48 <p>When you activate the Free plugin, no new top-level menu is added — most configuration happens directly on your <strong>product attribute</strong> pages (covered in the next chapter). The Free plugin does add an <strong>Chiseiko Essential Swatches Settings</strong> tab under <strong>WooCommerce → Settings</strong>, where you can adjust swatch layout and turn on the optional interactive archive swatches (see <a href="{{CH:interactive-archive-swatches}}">Chapter 7</a>).</p>50 <p>When you activate the Free plugin, no new top-level menu is added — most configuration happens directly on your <strong>product attribute</strong> pages (covered in the next chapter). The Free plugin does add an <strong>Chiseiko Essential Swatches Settings</strong> tab under <strong>WooCommerce → Settings</strong>, where you can adjust swatch layout and turn on the optional interactive archive swatches (see Chapter 7 in the Pro user guide).</p> 49 51 <p><img width="2400" height="3192" loading="lazy" decoding="async" src="images/free/settings.webp" alt="The free plugin's settings under WooCommerce → Settings → Chiseiko Essential Swatches Settings"></p> 50 <p>When you activate the Pro add-on, a new settings page appears at <strong>WooCommerce → Chiseiko Essential Swatches Pro</strong>. This is where you manage your license and enable/disable the Pro modules. Until you enter a key, the License tab shows <strong>No license</strong> — enter and activate your key to unlock the Pro modules (see <a href="{{CH:pro-license-and-modules}}">Chapter 5</a>).</p>52 <p>When you activate the Pro add-on, a new settings page appears at <strong>WooCommerce → Chiseiko Essential Swatches Pro</strong>. This is where you manage your license and enable/disable the Pro modules. Until you enter a key, the License tab shows <strong>No license</strong> — enter and activate your key to unlock the Pro modules (see Chapter 5 in the Pro user guide).</p> 51 53 <p><img width="2400" height="981" loading="lazy" decoding="async" src="images/pro/license-no-license.webp" alt="Freshly installed: the License tab shows “No license” until you activate your key"></p> 52 54 <hr> -
chiseiko-essential-swatches/trunk/docs/settings.html
r3598460 r3778841 4 4 <p><strong>WooCommerce → Settings → Chiseiko Essential Swatches Settings</strong></p> 5 5 <p><img width="2400" height="3192" loading="lazy" decoding="async" src="images/free/settings.webp" alt="The Chiseiko Essential Swatches Settings tab under WooCommerce → Settings"></p> 6 <p>The page has t wo sections: <strong>Product Page</strong> (how swatches behave on a single product) and <strong>Archive / Shop Page Swatches</strong> (how swatches behave on shop, category, and archive grids). After changing anything, scroll to the bottom and click <strong>Save changes</strong>.</p>6 <p>The page has three sections: <strong>Product Page</strong> (how swatches behave on a single product), <strong>Archive / Shop Page Swatches</strong> (how swatches behave on shop, category, and archive grids), and <strong>Appearance</strong> (the shape and size of color, image, and label swatches everywhere). After changing anything, scroll to the bottom and click <strong>Save changes</strong>.</p> 7 7 <blockquote> 8 8 <p><strong>Already using Pro?</strong> Several of these options are taken over by Pro modules when Pro is active — each setting below notes when that happens. With Pro installed, the matching controls live under <strong>WooCommerce → Chiseiko Essential Swatches Pro</strong>.</p> … … 121 121 </ul> 122 122 <blockquote> 123 <p><strong>With Chiseiko Essential Swatches Pro active</strong>, the Pro tooltip engine (custom position, hover delay, per-term overrides) automatically takes over on single product pages while this setting is on. See <a href="{{CH:advanced-styling}}">Chapter 9 — Advanced Styling</a>and the Pro tooltips module.</p>123 <p><strong>With Chiseiko Essential Swatches Pro active</strong>, the Pro tooltip engine (custom position, hover delay, per-term overrides) automatically takes over on single product pages while this setting is on. See Chapter 9 — Advanced Styling in the Pro user guide and the Pro tooltips module.</p> 124 124 </blockquote> 125 125 <h3 id="attribute-row-alignment">Attribute Row Alignment</h3> … … 143 143 <p>By default, swatches on archive pages are a <strong>read-only preview strip</strong> under each product card: customers see the available options at a glance but click through to the product page to choose. The settings below let you make that strip interactive.</p> 144 144 <blockquote> 145 <p><strong>Pro users:</strong> these options are managed in <strong>WooCommerce → Chiseiko Essential Swatches Pro → Archive Swatches</strong>, and the Pro module overrides the free settings here. See <a href="{{CH:interactive-archive-swatches}}">Chapter 7 — Interactive Archive Swatches</a>.</p>145 <p><strong>Pro users:</strong> these options are managed in <strong>WooCommerce → Chiseiko Essential Swatches Pro → Archive Swatches</strong>, and the Pro module overrides the free settings here. See Chapter 7 — Interactive Archive Swatches in the Pro user guide.</p> 146 146 </blockquote> 147 147 <h3 id="interactive-archive-swatches">Interactive Archive Swatches</h3> … … 178 178 <blockquote> 179 179 <p><strong>When Chiseiko Essential Swatches Pro is active</strong>, its matching setting takes precedence over this one.</p> 180 </blockquote> 181 <hr> 182 <h2 id="section-3--appearance">Section 3 — Appearance</h2> 183 <p>These options set the look of your swatches across the whole store — product pages, shop and category grids, and related products.</p> 184 <h3 id="swatch-shape">Swatch Shape</h3> 185 <p><strong>Default: Circle.</strong> Applies to color, image, and label swatches. Radio buttons keep their own shape.</p> 186 <ul> 187 <li><strong>Circle</strong> — every swatch is the same round size. Short labels such as S, M, or XL fit; longer labels are cut off ("Medium" shows as "Medi").</li> 188 <li><strong>Rounded square</strong> — softly rounded corners. Label swatches widen to fit their text.</li> 189 <li><strong>Square</strong> — sharp corners. Label swatches widen to fit their text.</li> 190 </ul> 191 <blockquote> 192 <p><strong>Tip:</strong> If your labels are longer than two or three characters, choose <strong>Rounded square</strong> or <strong>Square</strong>. On a shop card, a label too long for the card ends in "…"; the full name still shows on hover and is read out by screen readers.</p> 193 </blockquote> 194 <p>For other looks — for example pill-shaped labels — see <a href="{{CH:customizing-swatches}}">Chapter 25 — Customizing Swatches</a>.</p> 195 <h3 id="swatch-size-px">Swatch Size (px)</h3> 196 <p><strong>Default: 32.</strong></p> 197 <p>The width and height of color and image swatches on desktop screens, from <strong>24</strong> to <strong>64</strong> pixels. Phones and tablets always keep <strong>44-pixel</strong> swatches so they stay comfortable to tap, whatever you choose here.</p> 198 <blockquote> 199 <p><strong>When Chiseiko Essential Swatches Pro is active with a valid license</strong>, this section is hidden: Pro's <strong>Advanced Styling</strong> module controls swatch shape and size instead (see Chapter 9 — Advanced Styling in the Pro user guide).</p> 180 200 </blockquote> 181 201 <hr> … … 190 210 </ul> 191 211 </li> 192 <li><strong>Pro takes the wheel where noted.</strong> Tooltips, attribute-row alignment, related-product swatches, and the whole archive section are handed to the equivalent Pro module when Pro is active — the free values act as the baseline until then.</li>193 </ul> 194 <hr> 212 <li><strong>Pro takes the wheel where noted.</strong> Tooltips, attribute-row alignment, related-product swatches, the whole archive section, and swatch shape and size are handed to the equivalent Pro module when Pro is active with a valid license — the free values act as the baseline until then.</li> 213 </ul> 214 <hr> -
chiseiko-essential-swatches/trunk/docs/variable-products.html
r3598460 r3778841 90 90 <li>Only terms that have a swatch <strong>type</strong> set (color, image, text label, or radio) show in the loop preview. Terms left at "— Select type —" are skipped.</li> 91 91 <li>Sizes and other terms with no swatch type set are hidden from the loop to keep things clean. (If you explicitly give a size term a Text Label or Radio Button swatch type, it <em>will</em> appear.)</li> 92 <li>By default these loop swatches are <strong>read-only</strong>, but the Free plugin includes an optional <strong>Interactive Archive Swatches</strong> setting (under <strong>WooCommerce → Settings → Chiseiko Essential Swatches Settings</strong>, off by default) that makes them clickable, with optional AJAX add-to-cart. Pro extends this further — see <a href="{{CH:interactive-archive-swatches}}">Chapter 7</a>.</li>92 <li>By default these loop swatches are <strong>read-only</strong>, but the Free plugin includes an optional <strong>Interactive Archive Swatches</strong> setting (under <strong>WooCommerce → Settings → Chiseiko Essential Swatches Settings</strong>, off by default) that makes them clickable, with optional AJAX add-to-cart. Pro extends this further — see Chapter 7 in the Pro user guide.</li> 93 93 <li>Swatches are displayed in <strong>alphabetical order</strong> by the term name (A → Z). For example, if your colors are Ivory, Rose, and Sage, they will always appear in that order: Ivory, Rose, Sage — regardless of the order you created them in.</li> 94 94 </ul> … … 102 102 <li>At least one variation has been created and has a price.</li> 103 103 </ol> 104 <p>Still not working? See <a href="{{CH:troubleshooting}}">Chapter 24 — Troubleshooting</a>.</p>104 <p>Still not working? Ask in the <a href="https://wordpress.org/support/plugin/chiseiko-essential-swatches/">WordPress.org support forum</a>, or see Chapter 24 — Troubleshooting in the Pro user guide.</p> 105 105 <hr> 106 106 <h2 id="working-with-multiple-attributes">Working with Multiple Attributes</h2> -
chiseiko-essential-swatches/trunk/includes/class-chiseikoessw-ajax-batch.php
r3598460 r3778841 316 316 } 317 317 318 /* @var \WC_Product_Variable $product */ // phpcs:ignore Squiz.PHP.CommentedOutCode.Found -- type narrowing for PHPStan after the is_type( 'variable' ) guard above; not commented-out code.318 /** @var \WC_Product_Variable $product */ // phpcs:ignore Generic.Commenting.DocComment.MissingShort -- inline PHPStan type narrowing after the is_type( 'variable' ) guard above. 319 319 $data = $this->build_variation_map( $product ); 320 320 -
chiseiko-essential-swatches/trunk/includes/class-chiseikoessw-frontend.php
r3598460 r3778841 259 259 } 260 260 261 // Card-strip layout (row flex + gap, archive alignment, two-row clamp, 262 // text/label treatment). The read-only strip renders on every card 263 // surface, so its stylesheet must load there whether or not interactive 264 // archive swatches are enabled; CHISEIKOESSW_Archive_Swatches enqueues 265 // the same handle (a no-op repeat) and adds only the interactive script. 266 if ( CHISEIKOESSW_Hooks::card_surface_active() ) { 267 wp_enqueue_style( 268 'chiseikoessw-archive', 269 CHISEIKOESSW_PLUGIN_URL . "assets/css/chiseikoessw-archive{$sfx}.css", 270 array( 'chiseikoessw-frontend', 'chiseikoessw-card-swatches' ), 271 CHISEIKOESSW_VERSION 272 ); 273 $align_css = CHISEIKOESSW_Swatch_Layout::archive_align_css(); 274 if ( '' !== $align_css ) { 275 wp_add_inline_style( 'chiseikoessw-frontend', $align_css ); 276 } 277 } 278 261 279 // JS is only needed on single product pages (where the variation form lives). 262 280 // Declared dependencies: -
chiseiko-essential-swatches/trunk/includes/class-chiseikoessw-settings.php
r3598460 r3778841 83 83 */ 84 84 public function get_settings(): array { 85 returnarray(85 $settings = array( 86 86 87 87 // ── Product page section ───────────────────────────────────────── … … 284 284 ), 285 285 ); 286 287 // Global shape/size apply to product and shop swatches alike, so they 288 // get their own section. Empty when Pro's Advanced Styling owns them. 289 $appearance = CHISEIKOESSW_Appearance::settings_fields(); 290 if ( empty( $appearance ) ) { 291 return $settings; 292 } 293 294 return array_merge( 295 $settings, 296 array( 297 array( 298 'title' => __( 'Appearance', 'chiseiko-essential-swatches' ), 299 'type' => 'title', 300 'desc' => __( 'Shape and size of color and image swatches across the store.', 'chiseiko-essential-swatches' ), 301 'id' => 'chiseikoessw_appearance_section', 302 ), 303 ), 304 $appearance, 305 array( 306 array( 307 'type' => 'sectionend', 308 'id' => 'chiseikoessw_appearance_section', 309 ), 310 ) 311 ); 286 312 } 287 313 -
chiseiko-essential-swatches/trunk/includes/class-chiseikoessw-swatch-layout.php
r3598460 r3778841 274 274 ++$this->group_index; 275 275 276 $hidden_attr = 'false' === $expanded ? ' hidden' : ''; 276 // Groups always start collapsed, so the divider and panel start hidden. 277 $hidden_attr = ' hidden'; 277 278 278 279 return sprintf( … … 426 427 ) 427 428 ); 428 429 // Output alignment as a CSS custom property so archive swatch groups 430 // can reference it without class toggling. 429 } 430 431 /** 432 * The archive alignment setting as a CSS custom property, read by every 433 * card-strip row (Free and Pro). Printed by CHISEIKOESSW_Frontend on card 434 * surfaces — not from enqueue_assets() — so it also applies when the 435 * layout is 'inline' and this module registers no hooks. Empty at the 436 * default ('center'): every consumer falls back to `center`. 437 */ 438 public static function archive_align_css(): string { 431 439 $align_map = array( 432 'left' => 'flex-start', 433 'center' => 'center', 434 'right' => 'flex-end', 435 ); 436 $flex_val = $align_map[ $alignment ] ?? 'center'; 437 wp_add_inline_style( 438 'chiseikoessw-frontend', 439 ':root{--chiseikoessw-archive-align:' . $flex_val . ';}' 440 ); 440 'left' => 'flex-start', 441 'right' => 'flex-end', 442 ); 443 $alignment = self::get_alignment(); 444 return isset( $align_map[ $alignment ] ) ? ':root{--chiseikoessw-archive-align:' . $align_map[ $alignment ] . ';}' : ''; 441 445 } 442 446 } -
chiseiko-essential-swatches/trunk/includes/class-chiseikoessw-term-meta.php
r3598460 r3778841 104 104 * 105 105 * Reads the stored meta value and validates it against ALLOWED_TYPES. 106 * Falls back to 'none' for: 106 * A term without its own type inherits its attribute's default swatch 107 * type (CHISEIKOESSW_Attribute_Defaults), when one is set. 108 * Otherwise falls back to 'none' for: 107 109 * - Terms with no meta set yet (new terms). 108 110 * - Any stored value that is no longer in the allowlist. … … 115 117 public static function get_type( int $term_id ): string { 116 118 $type = (string) get_term_meta( $term_id, self::META_TYPE, true ); 119 // No own swatch type ('' when never saved, 'none' when the term form was 120 // saved without picking one): inherit the attribute's default swatch 121 // type, if any. A real per-term type always wins. Stores without any 122 // attribute defaults skip the get_term() lookup entirely. 123 if ( ( '' === $type || 'none' === $type ) && class_exists( 'CHISEIKOESSW_Attribute_Defaults' ) && array() !== CHISEIKOESSW_Attribute_Defaults::all() ) { 124 $term = get_term( $term_id ); 125 if ( $term && isset( $term->taxonomy ) ) { 126 $type = CHISEIKOESSW_Attribute_Defaults::get_default_type( (string) $term->taxonomy ); 127 } 128 } 117 129 // Legacy alias: pre-radio releases stored the text-pill swatch as 118 130 // 'text'. The current allowlist uses 'label' for that slot, so coerce -
chiseiko-essential-swatches/trunk/includes/class-chiseikoessw-user-guide.php
r3598460 r3778841 34 34 */ 35 35 private string $hook = ''; 36 37 /** 38 * Admin URL of the user guide, for links elsewhere in the plugin. 39 * 40 * The Free page is not registered when the Pro add-on is installed (Pro 41 * ships the complete guide in its own settings tab), so Pro filters this 42 * to that tab. 43 */ 44 public static function url(): string { 45 /** 46 * Filters the admin URL the plugin links to for its user guide. 47 * 48 * @param string $url URL of the Free guide page. 49 */ 50 return (string) apply_filters( 'chiseikoessw_user_guide_url', add_query_arg( 'page', self::SLUG, admin_url( 'admin.php' ) ) ); 51 } 36 52 37 53 /** … … 144 160 class="<?php echo $current === $chapter['slug'] ? 'is-active' : ''; ?>" 145 161 <?php echo $current === $chapter['slug'] ? 'aria-current="page"' : ''; ?>> 146 <span class="chiseikoessw-guide__num"><?php echo esc_html( (string) ( $ i + 1 ) ); ?></span>162 <span class="chiseikoessw-guide__num"><?php echo esc_html( (string) ( $chapter['num'] ?? $i + 1 ) ); ?></span> 147 163 <?php echo esc_html( $chapter['title'] ); ?> 148 164 </a> … … 150 166 <?php endforeach; ?> 151 167 </ol> 152 <p class="chiseikoessw-guide__note"><?php esc_html_e( 'Unlock 23Pro modules and the full guide with Chiseiko Essential Swatches Pro.', 'chiseiko-essential-swatches' ); ?></p>168 <p class="chiseikoessw-guide__note"><?php esc_html_e( 'Unlock the Pro modules and the full guide with Chiseiko Essential Swatches Pro.', 'chiseiko-essential-swatches' ); ?></p> 153 169 </nav> 154 170 <article class="chiseikoessw-guide__content"> -
chiseiko-essential-swatches/trunk/readme.txt
r3598460 r3778841 1 1 === Chiseiko Essential Swatches for WooCommerce === 2 2 Contributors: chiseiko 3 Tags: variation swatches, color swatches, image swatches, product variations, woocommerce 3 4 Donate link: https://www.paypal.com/ncp/payment/GBS4FG84LUEMY 4 Tags: woocommerce, variation swatches, color swatches, image swatches, product variations5 5 Requires at least: 6.5 6 Tested up to: 7.0 6 Tested up to: 7.1 7 Requires PHP: 8.1 7 8 WC requires at least: 8.0 8 WC tested up to: 10.5 9 Requires PHP: 8.1 10 Stable tag: 1.0.0 11 License: GPL-2.0-or-later 9 WC tested up to: 11.2.1 10 Stable tag: 1.1.0 11 License: GPLv2 or later 12 12 License URI: https://www.gnu.org/licenses/gpl-2.0.html 13 13 14 Turn WooCommerce variation dropdowns into clickable color, image, text & button swatches on product and shop pages. Sell more variations, fast.14 Lightweight WooCommerce variation swatches. Replace plain dropdowns with fast, visual color, image, and text swatches on product and shop pages. 15 15 16 16 == Description == 17 17 18 **Chiseiko Essential Swatches turns plain WooCommerce variation dropdowns into beautiful, clickable color, image, text, and button swatches** — on single product pages *and*shop, category, and tag archives. Shoppers see their options at a glance, pick the right variation in one click, and add to cart faster.18 Chiseiko Essential Swatches turns plain WooCommerce variation dropdowns into beautiful, clickable color, image, text, and button swatches — on single product pages and shop, category, and tag archives. Shoppers see their options at a glance, pick the right variation in one click, and add to cart faster. 19 19 20 Built from the ground up with a vanilla-first JavaScript architecture, conditional asset loading, and full accessibility. It works with any WooCommerce-compatible theme — Classic, FSE block themes, and page builders (Elementor, Divi, Beaver Builder) — with no template edits and no shortcodes. 20 = Lightweight & Fast = 21 Speed matters for conversions. Built for performance from day one: 22 * **Vanilla JavaScript Core:** Built in vanilla JS with no jQuery code of its own (only hooking into unavoidable WooCommerce core events). 23 * **Conditional Asset Loading:** Scripts and styles load *only* on product and shop pages. 24 * **Batch AJAX:** Archive swatch data is fetched via a single batched request per page, rather than punishing your server with one request per product. 21 25 22 26 = The problem with default WooCommerce variations = 23 24 27 Out of the box, WooCommerce hides every product variation behind a generic `<select>` dropdown. That quietly costs you sales: 25 26 * Customers can't *see* the colors or styles you sell — they have to open a menu and read text. 28 * Customers can't see the colors or styles you sell — they have to open a menu and read text. 27 29 * Available options stay hidden until the dropdown is opened, so shoppers miss variants. 28 30 * There's no visual feedback on mobile, where dropdowns are slow and fiddly. 29 31 * Shop and category pages show no variation choices at all, so every selection means an extra page load. 30 32 31 = What Chiseiko Essential Swatches solves = 32 33 * **Makes choices visual and instant.** Real color circles, product photos, and styled labels replace text dropdowns, so shoppers recognize what they want immediately. 34 * **Shows options on the shop page, not just the product page.** Interactive archive swatches let customers preview and even add a variant to the cart straight from the product card. 35 * **Reduces "out of stock" frustration.** Unavailable variants are dimmed (not hidden), so customers always see the full range and what's available. 36 * **Speeds up the path to purchase.** Instant gallery preview, mobile auto-scroll, and one-click selection shorten the distance between landing and buying. 37 * **Keeps your store fast.** Assets load only on the pages that need them, and archive data is fetched in a single batched request — not one request per product. 33 = How it works = 34 Go to Products > Attributes and edit any global attribute. For each term, choose a swatch type (color, image, label, or radio) and configure it — or set a default swatch type on the attribute itself to turn every term into label or radio buttons in one step. Swatches appear automatically on every product that uses that attribute — no shortcodes or template edits required. Local (custom per-product) attributes render as text pills automatically. A short getting-started notice after activation points you to the right screens. 38 35 39 36 = Swatch types (all four included free) = 40 41 37 * **Color Swatches** — Pick any hex color for each attribute term. 42 38 * **Image Swatches** — Upload a thumbnail from the Media Library. 43 39 * **Text Pills** — Styled labels for attributes without a visual representation. 44 40 * **Radio Buttons** — Round radio indicators with label text for simple selections. 41 * **Attribute-wide Defaults** — Show every term of an attribute (such as Size) as label or radio buttons without editing each term; individual terms can still set their own type. 42 43 = Look & feel = 44 * **Global Shape & Size** — Circle, rounded square, or square swatches at any size from 24 to 64 px. With rounded or square, label swatches widen to fit their text. Touch screens keep comfortable 44 px tap targets. 45 * **Tooltips** — Term names appear on hover and keyboard focus. 46 * **Attribute Row Alignment** — Keep each attribute name aligned with its row of swatches, whatever your theme does by default. 45 47 46 48 = Single product page = 47 48 * **Instant Gallery Preview** — The product gallery updates the moment a swatch is clicked, before all attributes are selected (Amazon/AliExpress-style image preview). 49 * **Smart Inventory UX** — Out-of-stock swatches are visually dimmed (not hidden), so customers always see available options. The last viable variant is auto-selected. 50 * **Layout Options** — Inline, accordion (collapsible), overflow ("Show more"), or slider layouts for products with many swatches. Accordion can be set to mobile-only. 51 * **Mobile Auto-Scroll** — After selecting a variant on mobile, the viewport scrolls to the gallery so the customer sees the updated image. Configurable breakpoint and offset. 52 * **Accessible** — Full ARIA support with `role="radiogroup"`, `aria-checked`, `aria-disabled`, `aria-label`, and roving-tabindex keyboard navigation. 49 * **Instant Gallery Preview** — The product gallery updates the moment a swatch is clicked. 50 * **Smart Inventory UX** — Out-of-stock swatches are visually dimmed (not hidden), so customers always see available options. 51 * **Layout Options** — Inline, accordion (collapsible), overflow (“Show more”), or slider layouts. 52 * **Mobile Auto-Scroll** — Auto-scrolls to the gallery after selection so mobile users see the updated image. 53 * **Accessible** — Full ARIA support for keyboard navigation and screen readers. 53 54 54 55 = Shop & archive pages = 56 * **Interactive Archive Swatches** — Clickable swatches on product cards so customers can preview variants directly from the catalog. 57 * **AJAX Add to Cart** — An “Add to Cart” button appears right on the grid after selection. 58 * **Catalog Mode** — Show only one attribute (like Color) on archives for a cleaner layout. 59 * **Related & Upsell Products** — The same interactive swatches appear on related, upsell, and cross-sell product cards on product pages. 55 60 56 * **Archive Swatch Strip** — Compact swatch previews on shop, category, and tag pages. 57 * **Interactive Archive Swatches** — Clickable swatches on product cards so customers can preview variants without leaving the listing. 58 * **AJAX Add to Cart** — After selecting a swatch on an archive page, an "Add to Cart" button appears on the card — no need to open the product page. 59 * **Catalog Mode** — Show only one attribute on archive pages for a cleaner layout. 61 = Free vs Pro = 62 The free plugin is a complete swatch solution with no caps on the number of swatches, attributes, or products. 60 63 61 = Performance & compatibility = 62 63 * **Vanilla-first JavaScript** — plugin-owned behavior stays native. Any jQuery that remains is limited to unavoidable WooCommerce or WordPress bridge contracts. 64 * **Conditional Loading** — CSS and JS load only on product and shop pages. Nothing loads on cart, checkout, or account pages. 65 * **Batch AJAX** — Archive swatch data is fetched via a single batched request per page (up to 50 products), then cached. 66 * **Theme-agnostic** — Uses WooCommerce's standard variation form hooks; no template overrides. 67 68 = How it works = 69 70 1. Go to **Products > Attributes** and edit any global attribute. 71 2. For each term, choose a swatch type (color, image, label, or radio) and configure it. 72 3. Swatches appear automatically on every product that uses that attribute — no shortcodes or template edits required. 73 74 Local (custom per-product) attributes render as text pills automatically. 75 76 = Free vs Pro — which problems does each solve? = 77 78 **Chiseiko Essential Swatches (free) is a complete swatch solution.** If your goal is to replace variation dropdowns with visual swatches on product *and* shop pages, add interactive archive selection with AJAX add-to-cart, control layout, and keep everything fast and accessible — the free plugin does that, with no limits on the number of swatches, attributes, or products. 79 80 **Upgrade to [Chiseiko Essential Swatches Pro](https://chiseikotech.com/chiseiko-essential-swatches-pro/) when you outgrow the basics** and need to solve store-growth problems the free plugin intentionally leaves out: 81 82 * *"My 'variations' are actually separate products and I don't want to lose their SEO."* → **Linked Simple Products** ties standalone simple products together into one swatch strip while preserving an individual, indexable URL per variant — plus canonical consolidation, linked archive swatches, a multi-attribute matrix (e.g. color + size), an in-place product-page swap (no full reload), and a **shared review collection** with a combined rating across the group. 83 * *"My swatches look generic and off-brand."* → **Advanced Styling** adds per-swatch shapes, a multi-stop gradient builder, custom radius, out-of-stock display modes (cross-out / blur / hide), and one-click style presets — plus configurable **tooltips**. 84 * *"Shoppers can't filter by color or brand."* → A visual **Swatch Filter Widget** and **WooCommerce Brands** swatches (including on shop-archive cards). 85 * *"I need to manage hundreds of products without clicking through every term."* → **CSV Import/Export**, **Auto-Assign Images** by slug, and a **Variable → Simple migration tool** that copies brands, custom fields, taxonomies, galleries, and reviews. 86 * *"I want to lift average order value and mobile conversions."* → **Dynamic Price Sync**, **Attribute-Based Extra Fees**, and a mobile **Sticky Add-to-Cart Bar**. 87 * *"My big variable products are slow, and quick-view breaks my swatches."* → **AJAX Variation Override** (raise the inline-variation limit), **Additional Variation Images**, **Swatch Grouping**, and **Quick View Compatibility**. 88 * *"I run a multilingual store."* → **Multilingual Sync** keeps swatch metadata aligned across WPML and Polylang. 89 90 Every Pro module is individually toggleable, loads conditionally, and follows the same vanilla-first architecture as the free plugin. 64 Upgrade to [Chiseiko Essential Swatches Pro](https://chiseikotech.com/chiseiko-essential-swatches-pro/) when you need advanced tools for a growing store: 65 * **Linked Simple Products:** Tie standalone simple products together into one swatch strip while keeping an indexable URL per variant. 66 * **Advanced Styling:** Custom shapes, gradients, tooltips, and out-of-stock display modes (cross-out / blur / hide). 67 * **Swatch Filter Widget:** Let shoppers filter your catalog by color or brand. 68 * **Bulk Management:** CSV Import/Export, Variable-to-Simple migration, and Auto-Assign Images. 69 * **Conversion Tools:** Dynamic Price Sync, Attribute-Based Extra Fees, and a Sticky Mobile Add-to-Cart bar. 70 * **Scale & Compatibility:** AJAX Variation Override for large catalogs, Multilingual Sync (WPML/Polylang), and Quick View support. 91 71 92 72 == Installation == 93 73 94 1. Upload the `chiseiko-essential-swatches` folder to ` wp-content/plugins/`, or install directly from the WordPress plugin screen.74 1. Upload the `chiseiko-essential-swatches` folder to `/wp-content/plugins/`, or install directly from the WordPress plugin screen. 95 75 2. Activate the plugin. 96 76 3. Ensure WooCommerce 8.0 or later is active. 97 4. Go to **Products > Attributes**, edit an attribute, and configure swatch types for each term.98 5. Optionally configure settings at **WooCommerce > Settings > Chiseiko Essential Swatches Settings** (image preview, archive swatches, AJAX add-to-cart, layout mode, catalog mode, mobile auto-scroll).77 4. Go to Products > Attributes, edit an attribute, and configure swatch types for each term — or choose a default swatch type for the whole attribute. 78 5. Optionally configure settings (layout, shape, size, tooltips) at WooCommerce > Settings > Chiseiko Essential Swatches Settings. The plugin's row on the Plugins screen links straight there and to the built-in guide. 99 79 100 80 == Frequently Asked Questions == 101 81 102 82 = Do I need WooCommerce? = 103 104 Yes. Chiseiko Essential Swatches requires WooCommerce 8.0 or later (tested up to WooCommerce 10.5). 83 Yes. Chiseiko Essential Swatches requires WooCommerce 8.0 or later (tested up to WooCommerce 11.2.1). 105 84 106 85 = Is it really free? = 107 108 86 Yes. The free plugin includes all four swatch types, single-product and archive swatches, interactive archive swatches with AJAX add-to-cart, every layout mode, catalog mode, and mobile auto-scroll — with no caps on swatches, attributes, or products. Pro is an optional add-on for advanced features. 109 87 88 = Does the plugin slow down my site? = 89 No. All plugin-owned JavaScript is vanilla. Assets load only on product and shop pages. Archive swatch data is cached and served via a single batched AJAX endpoint to protect server performance. 90 110 91 = Will it work with my theme? = 111 112 92 Chiseiko Essential Swatches uses WooCommerce's standard variation form hooks and does not override templates, so it is compatible with any properly built WooCommerce theme — including Classic themes, FSE block themes, and page builders (Elementor, Divi, Beaver Builder). 113 93 114 94 = Does it work with custom (local) product attributes? = 95 Yes. Local attributes automatically render as text-pill swatches. To use color or image swatches, convert them to global attributes under Products > Attributes. 115 96 116 Yes. Local attributes automatically render as text-pill swatches. To use color or image swatches, convert them to global attributes under **Products > Attributes**. 117 118 = Does the plugin slow down my site? = 119 120 No. All plugin-owned JavaScript is vanilla (no jQuery runtime dependency). Assets load only on product and shop pages. Archive swatch data is cached and served via a single batched AJAX endpoint, and frontend scripts use the WP 6.3+ `defer` strategy for non-blocking loading. 121 122 = What swatch types are available? = 123 124 Four: Color (hex picker), Image (Media Library thumbnail), Label (text pill), and Radio Button. All four are in the free version. 97 = Can I show swatches on the shop and category pages? = 98 Yes. Enable archive swatches in settings. You can also make them interactive so customers preview variants and add to cart directly from product cards, or use Catalog Mode to show a single attribute for a cleaner grid. 125 99 126 100 = Can I control the layout for products with many swatches? = 127 128 Yes. Choose inline (default), accordion (collapsible panels per attribute), overflow ("Show N more" toggle), or slider. Accordion can be set to mobile-only, and the overflow limit is configurable. 129 130 = Can I show swatches on the shop and category pages? = 131 132 Yes. Enable archive swatches in settings. You can also make them interactive so customers preview variants and add to cart directly from product cards, or use Catalog Mode to show a single attribute for a cleaner grid. 101 Yes. Choose inline (default), accordion (collapsible panels per attribute), overflow (“Show N more” toggle), or slider. Accordion can be set to mobile-only, and the overflow limit is configurable. 133 102 134 103 = Can I hide swatches on archive pages? = 135 136 104 Yes. Disable archive swatches in settings, or return `false` from the `chiseikoessw_render_loop_swatches` filter to suppress per-product. 137 105 138 106 = Is the plugin translatable? = 139 140 107 Yes. All strings use the `chiseiko-essential-swatches` text domain and are translation-ready. 141 142 = What is the difference between Free and Pro? =143 144 The free plugin is a complete swatch solution: four swatch types, instant gallery preview, interactive archive swatches with AJAX add-to-cart, layout options (inline / accordion / overflow / slider), catalog mode, and mobile auto-scroll. [Chiseiko Essential Swatches Pro](https://chiseikotech.com/chiseiko-essential-swatches-pro/) adds linked simple products (SEO-friendly swatches across separate listings) with grouping, canonical shield, archive swatches, multi-attribute matrix, in-place product-page swap, and shared reviews; advanced styling (gradients, shapes, tooltips, style presets, OOS display modes); a swatch filter widget; WooCommerce Brands swatches; variation-threshold management; additional variation images; swatch grouping; CSV bulk operations; auto-assign images; multilingual sync; quick-view compatibility; dynamic price sync; attribute-based extra fees; a sticky mobile add-to-cart bar; gallery zoom alignment; and a Variable → Simple migration tool. See the Free vs Pro section above for the specific problems each solves.145 108 146 109 == Screenshots == … … 153 116 6. Catalog Mode — a single attribute (Color) shown per product card across shop and category archives. 154 117 118 == Upgrade Notice == 119 120 = 1.1.0 = 121 Adds an attribute-wide default swatch type, global swatch shape and size, and a short getting-started guide for new stores. 122 123 = 1.0.0 = 124 Initial release. 125 155 126 == Changelog == 127 128 = 1.1.0 = 129 * New: Attribute-wide default swatch type — show every term of an attribute (such as Size) as label or radio buttons in one step. Individual terms can still choose their own type. 130 * New: Global swatch shape (circle, rounded square, square) for color, image, and label swatches on product pages and shop, category, and related-product cards — with rounded square or square, label swatches widen to fit their text. Global swatch size (24–64 px) on desktop; touch screens keep 44 px tap targets. 131 * New: Getting-started notice after activation that points to the attribute and settings screens. 132 * New: Settings and Guide links on the plugin's row in the Plugins screen. 133 * New: An occasional, dismissible review request, shown only on the plugin's own screens to store managers — for WordPress.org, or for Pro on chiseikotech.com when Pro is installed. 134 * New: "Customizing Swatches" chapter in the built-in guide — tested CSS and PHP examples, including how to let long labels fit their swatch. 135 * Fix: Shop and category swatch strips (and related-product cards) are laid out correctly — spaced, aligned, and limited to two rows — when interactive archive swatches are off, which is the default. 136 * Fix: The archive swatch alignment setting (left, center, right) now applies with the default inline layout. 137 * Fix: Long swatch labels no longer make one product card wider than the others in grid themes such as Astra. Labels too long for a card end in "…", and the full name stays in the tooltip and screen-reader label. 138 * Fix: Links in the built-in guide no longer point to chapters that only ship with Pro. 139 * Maintenance: tested with WordPress 7.1.4 and WooCommerce 11.2.1. 156 140 157 141 = 1.0.0 = … … 169 153 * Variation direct links (URL query parameter pre-selection). 170 154 * Developer hooks: `chiseikoessw_swatch_types`, `chiseikoessw_swatch_button_classes`, `chiseikoessw_swatch_button_html`, `chiseikoessw_swatch_group_html`, `chiseikoessw_render_loop_swatches`, plus action hooks. 171 172 == Upgrade Notice ==173 174 = 1.0.0 =175 Initial release. -
chiseiko-essential-swatches/trunk/uninstall.php
r3598460 r3778841 75 75 'chiseikoessw_archive_swatch_alignment', 76 76 'chiseikoessw_catalog_attribute', 77 // Review notice (CHISEIKOESSW_Review_Notice::OPTION_INSTALLED_AT). 78 'chiseikoessw_installed_at', 79 // Attribute-level default swatch types (CHISEIKOESSW_Attribute_Defaults::OPTION). 80 'chiseikoessw_attribute_default_types', 81 // Global swatch shape / size (CHISEIKOESSW_Appearance). 82 'chiseikoessw_swatch_shape', 83 'chiseikoessw_swatch_size', 77 84 ); 78 85 … … 80 87 delete_option( $option_key ); 81 88 } 89 90 // ── Remove per-user admin notice state ─────────────────────────────── 91 // Mirrors CHISEIKOESSW_Review_Notice::META_DISMISSED / META_SNOOZED_UNTIL. 92 delete_metadata( 'user', 0, 'chiseikoessw_review_dismissed', '', true ); 93 delete_metadata( 'user', 0, 'chiseikoessw_review_snoozed_until', '', true ); 94 // CHISEIKOESSW_Onboarding_Notice::META_DISMISSED. 95 delete_metadata( 'user', 0, 'chiseikoessw_onboarding_dismissed', '', true ); 96 delete_transient( 'chiseikoessw_review_has_swatches' ); 82 97 83 98 // ── Remove plugin transients ─────────────────────────────────────────
Note:
See TracChangeset
for help on using the changeset viewer.
![(please configure the [header_logo] section in trac.ini)](/chrome/site/your_project_logo.png)