1
0
Fork 0

feat: Upgrade to TailwindCSS 4 & DaisyUI 5 (#263)

Also fixes #251

Reviewed-on: https://codeberg.org/freesewing/freesewing/pulls/263
Co-authored-by: joostdecock <joost@joost.at>
Co-committed-by: joostdecock <joost@joost.at>
This commit is contained in:
joostdecock 2025-04-18 08:07:13 +00:00 committed by Joost De Cock
parent a2863e5158
commit 44e04a4cef
164 changed files with 2361 additions and 2658 deletions

View file

@ -1,39 +1,53 @@
<p align='center'><a
href="https://www.npmjs.com/package/@freesewing/core"
title="@freesewing/core on NPM"
><img src="https://img.shields.io/npm/v/@freesewing/core.svg"
alt="@freesewing/core on NPM"/>
</a><a
href="https://opensource.org/licenses/MIT"
title="License: MIT"
><img src="https://img.shields.io/npm/l/@freesewing/core.svg?label=License"
alt="License: MIT"/>
</a><a
href="https://deepscan.io/dashboard#view=project&tid=2114&pid=2993&bid=23256"
title="Code quality on DeepScan"
><img src="https://deepscan.io/api/teams/2114/projects/2993/branches/23256/badge/grade.svg"
alt="DeepScan grade"
></a> <a
href="https://github.com/freesewing/freesewing/issues?q=is%3Aissue+is%3Aopen"
title="Open issues tagged pkg:aaron"
><img src="https://img.shields.io/github/issues/freesewing/freesewing.svg?label=Issues"
alt="Open issues"/>
</a><a
href="#contributors-"
title="All Contributors"
><img src="https://img.shields.io/badge/all_contributors-131-pink.svg"
alt="All Contributors"/>
</a></p><p align='center'><a
href="https://discord.freesewing.org"
title="Chat with us on Discord"
><img src="https://img.shields.io/discord/698854858052075530?label=Chat%20on%20Discord"
alt="Chat with us on Discord"/>
</a><a
href="https://freesewing.org/patrons/join"
title="Become a FreeSewing Patron"
><img src="https://img.shields.io/badge/%F3%A0%80%A0-Support%20us-blueviolet.svg?logo=cash-app&logoColor=white&logoWidth=15"
alt="Become a FreeSewing Patron"/>
</a></p>
href="https://www.npmjs.com/package/@freesewing/core"
title="@freesewing/core on NPM"
><img
src="https://img.shields.io/npm/v/@freesewing/core.svg"
alt="@freesewing/core on NPM"/>
</a> <a
href="https://opensource.org/licenses/MIT"
title="License: MIT"
><img
src="https://img.shields.io/npm/l/@freesewing/core.svg?label=License"
alt="License: MIT"/>
</a> <a
href="https://deepscan.io/dashboard#view=project&tid=2114&pid=2993&bid=23256"
title="Code quality on DeepScan"
><img
src="https://deepscan.io/api/teams/2114/projects/2993/branches/23256/badge/grade.svg"
alt="DeepScan grade"
></a> <a
href="https://codeberg.org/freesewing/freesewing/issues?q=is%3Aissue+is%3Aopen"
title="Open issues"
><img
src="https://img.shields.io/github/issues/freesewing/freesewing.svg?label=Issues"
alt="Open issues"/>
</a> <a
href="#contributors-"
title="All Contributors"
><img
src="https://img.shields.io/badge/all_contributors-131-pink.svg"
alt="All Contributors"/>
</a></p>
<p align='center'><a
href="https://forum.freesewing.eu"
title="Join the FreeSewing Forum"
><img
src="https://img.shields.io/discourse/users?server=https%3A%2F%2Fforum.freesewing.eu&label=Forum&color=%2385d996"
alt="Join the FreeSewing Forum"
/></a> <a
href="https://discord.freesewing.org"
title="Chat with us on Discord"
><img
src="https://img.shields.io/discord/698854858052075530?label=Chat%20on%20Discord"
alt="Chat with us on Discord"
/></a> <a
href="https://freesewing.org/patrons/join"
title="Become a FreeSewing Patron"
><img
src="https://img.shields.io/badge/%F3%A0%80%A0-Support%20us-blueviolet.svg?logo=cash-app&logoColor=white&logoWidth=15"
alt="Become a FreeSewing Patron"
/></a></p>
# FreeSewing

View file

@ -10,6 +10,7 @@
"plugin-mirror": "A FreeSewing plugin to mirror points or paths",
"plugin-ringsector": "A FreeSewing plugin to draft a ring sector (think part of a donut)",
"plugin-round": "A FreeSewing plugin to round corners",
"plugin-path-utils": "A FreeSewing plugin that adds various path helper macros",
"plugin-sprinkle": "A FreeSewing plugin to bulk-add snippets to your pattern",
"plugin-svgattr": "A FreeSewing plugin to set SVG attributes",
"plugin-theme": "A FreeSewing plugin that provides a default theme",

View file

@ -1,39 +1,53 @@
<p align='center'><a
href="https://www.npmjs.com/package/@freesewing/core"
title="@freesewing/core on NPM"
><img src="https://img.shields.io/npm/v/@freesewing/core.svg"
alt="@freesewing/core on NPM"/>
</a><a
href="https://opensource.org/licenses/MIT"
title="License: MIT"
><img src="https://img.shields.io/npm/l/@freesewing/core.svg?label=License"
alt="License: MIT"/>
</a><a
href="https://deepscan.io/dashboard#view=project&tid=2114&pid=2993&bid=23256"
title="Code quality on DeepScan"
><img src="https://deepscan.io/api/teams/2114/projects/2993/branches/23256/badge/grade.svg"
alt="DeepScan grade"
></a> <a
href="https://github.com/freesewing/freesewing/issues?q=is%3Aissue+is%3Aopen"
title="Open issues tagged pkg:aaron"
><img src="https://img.shields.io/github/issues/freesewing/freesewing.svg?label=Issues"
alt="Open issues"/>
</a><a
href="#contributors-"
title="All Contributors"
><img src="https://img.shields.io/badge/all_contributors-{{ allcontributors }}-pink.svg"
alt="All Contributors"/>
</a></p><p align='center'><a
href="https://discord.freesewing.org"
title="Chat with us on Discord"
><img src="https://img.shields.io/discord/698854858052075530?label=Chat%20on%20Discord"
alt="Chat with us on Discord"/>
</a><a
href="https://freesewing.org/patrons/join"
title="Become a FreeSewing Patron"
><img src="https://img.shields.io/badge/%F3%A0%80%A0-Support%20us-blueviolet.svg?logo=cash-app&logoColor=white&logoWidth=15"
alt="Become a FreeSewing Patron"/>
</a></p>
href="https://www.npmjs.com/package/@freesewing/core"
title="@freesewing/core on NPM"
><img
src="https://img.shields.io/npm/v/@freesewing/core.svg"
alt="@freesewing/core on NPM"/>
</a> <a
href="https://opensource.org/licenses/MIT"
title="License: MIT"
><img
src="https://img.shields.io/npm/l/@freesewing/core.svg?label=License"
alt="License: MIT"/>
</a> <a
href="https://deepscan.io/dashboard#view=project&tid=2114&pid=2993&bid=23256"
title="Code quality on DeepScan"
><img
src="https://deepscan.io/api/teams/2114/projects/2993/branches/23256/badge/grade.svg"
alt="DeepScan grade"
></a> <a
href="https://codeberg.org/freesewing/freesewing/issues?q=is%3Aissue+is%3Aopen"
title="Open issues"
><img
src="https://img.shields.io/github/issues/freesewing/freesewing.svg?label=Issues"
alt="Open issues"/>
</a> <a
href="#contributors-"
title="All Contributors"
><img
src="https://img.shields.io/badge/all_contributors-{{ allcontributors }}-pink.svg"
alt="All Contributors"/>
</a></p>
<p align='center'><a
href="https://forum.freesewing.eu"
title="Join the FreeSewing Forum"
><img
src="https://img.shields.io/discourse/users?server=https%3A%2F%2Fforum.freesewing.eu&label=Forum&color=%2385d996"
alt="Join the FreeSewing Forum"
/></a> <a
href="https://discord.freesewing.org"
title="Chat with us on Discord"
><img
src="https://img.shields.io/discord/698854858052075530?label=Chat%20on%20Discord"
alt="Chat with us on Discord"
/></a> <a
href="https://freesewing.org/patrons/join"
title="Become a FreeSewing Patron"
><img
src="https://img.shields.io/badge/%F3%A0%80%A0-Support%20us-blueviolet.svg?logo=cash-app&logoColor=white&logoWidth=15"
alt="Become a FreeSewing Patron"
/></a></p>
# FreeSewing

414
package-lock.json generated
View file

@ -31854,6 +31854,257 @@
"node": ">=14.16"
}
},
"node_modules/@tailwindcss/node": {
"version": "4.1.3",
"resolved": "https://registry.npmjs.org/@tailwindcss/node/-/node-4.1.3.tgz",
"integrity": "sha512-H/6r6IPFJkCfBJZ2dKZiPJ7Ueb2wbL592+9bQEl2r73qbX6yGnmQVIfiUvDRB2YI0a3PWDrzUwkvQx1XW1bNkA==",
"dev": true,
"license": "MIT",
"dependencies": {
"enhanced-resolve": "^5.18.1",
"jiti": "^2.4.2",
"lightningcss": "1.29.2",
"tailwindcss": "4.1.3"
}
},
"node_modules/@tailwindcss/node/node_modules/tailwindcss": {
"version": "4.1.3",
"resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.1.3.tgz",
"integrity": "sha512-2Q+rw9vy1WFXu5cIxlvsabCwhU2qUwodGq03ODhLJ0jW4ek5BUtoCsnLB0qG+m8AHgEsSJcJGDSDe06FXlP74g==",
"dev": true,
"license": "MIT"
},
"node_modules/@tailwindcss/oxide": {
"version": "4.1.3",
"resolved": "https://registry.npmjs.org/@tailwindcss/oxide/-/oxide-4.1.3.tgz",
"integrity": "sha512-t16lpHCU7LBxDe/8dCj9ntyNpXaSTAgxWm1u2XQP5NiIu4KGSyrDJJRlK9hJ4U9yJxx0UKCVI67MJWFNll5mOQ==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">= 10"
},
"optionalDependencies": {
"@tailwindcss/oxide-android-arm64": "4.1.3",
"@tailwindcss/oxide-darwin-arm64": "4.1.3",
"@tailwindcss/oxide-darwin-x64": "4.1.3",
"@tailwindcss/oxide-freebsd-x64": "4.1.3",
"@tailwindcss/oxide-linux-arm-gnueabihf": "4.1.3",
"@tailwindcss/oxide-linux-arm64-gnu": "4.1.3",
"@tailwindcss/oxide-linux-arm64-musl": "4.1.3",
"@tailwindcss/oxide-linux-x64-gnu": "4.1.3",
"@tailwindcss/oxide-linux-x64-musl": "4.1.3",
"@tailwindcss/oxide-win32-arm64-msvc": "4.1.3",
"@tailwindcss/oxide-win32-x64-msvc": "4.1.3"
}
},
"node_modules/@tailwindcss/oxide-android-arm64": {
"version": "4.1.3",
"resolved": "https://registry.npmjs.org/@tailwindcss/oxide-android-arm64/-/oxide-android-arm64-4.1.3.tgz",
"integrity": "sha512-cxklKjtNLwFl3mDYw4XpEfBY+G8ssSg9ADL4Wm6//5woi3XGqlxFsnV5Zb6v07dxw1NvEX2uoqsxO/zWQsgR+g==",
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"android"
],
"engines": {
"node": ">= 10"
}
},
"node_modules/@tailwindcss/oxide-darwin-arm64": {
"version": "4.1.3",
"resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-arm64/-/oxide-darwin-arm64-4.1.3.tgz",
"integrity": "sha512-mqkf2tLR5VCrjBvuRDwzKNShRu99gCAVMkVsaEOFvv6cCjlEKXRecPu9DEnxp6STk5z+Vlbh1M5zY3nQCXMXhw==",
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"darwin"
],
"engines": {
"node": ">= 10"
}
},
"node_modules/@tailwindcss/oxide-darwin-x64": {
"version": "4.1.3",
"resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-x64/-/oxide-darwin-x64-4.1.3.tgz",
"integrity": "sha512-7sGraGaWzXvCLyxrc7d+CCpUN3fYnkkcso3rCzwUmo/LteAl2ZGCDlGvDD8Y/1D3ngxT8KgDj1DSwOnNewKhmg==",
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"darwin"
],
"engines": {
"node": ">= 10"
}
},
"node_modules/@tailwindcss/oxide-freebsd-x64": {
"version": "4.1.3",
"resolved": "https://registry.npmjs.org/@tailwindcss/oxide-freebsd-x64/-/oxide-freebsd-x64-4.1.3.tgz",
"integrity": "sha512-E2+PbcbzIReaAYZe997wb9rId246yDkCwAakllAWSGqe6VTg9hHle67hfH6ExjpV2LSK/siRzBUs5wVff3RW9w==",
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"freebsd"
],
"engines": {
"node": ">= 10"
}
},
"node_modules/@tailwindcss/oxide-linux-arm-gnueabihf": {
"version": "4.1.3",
"resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm-gnueabihf/-/oxide-linux-arm-gnueabihf-4.1.3.tgz",
"integrity": "sha512-GvfbJ8wjSSjbLFFE3UYz4Eh8i4L6GiEYqCtA8j2Zd2oXriPuom/Ah/64pg/szWycQpzRnbDiJozoxFU2oJZyfg==",
"cpu": [
"arm"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">= 10"
}
},
"node_modules/@tailwindcss/oxide-linux-arm64-gnu": {
"version": "4.1.3",
"resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-gnu/-/oxide-linux-arm64-gnu-4.1.3.tgz",
"integrity": "sha512-35UkuCWQTeG9BHcBQXndDOrpsnt3Pj9NVIB4CgNiKmpG8GnCNXeMczkUpOoqcOhO6Cc/mM2W7kaQ/MTEENDDXg==",
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">= 10"
}
},
"node_modules/@tailwindcss/oxide-linux-arm64-musl": {
"version": "4.1.3",
"resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-musl/-/oxide-linux-arm64-musl-4.1.3.tgz",
"integrity": "sha512-dm18aQiML5QCj9DQo7wMbt1Z2tl3Giht54uVR87a84X8qRtuXxUqnKQkRDK5B4bCOmcZ580lF9YcoMkbDYTXHQ==",
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">= 10"
}
},
"node_modules/@tailwindcss/oxide-linux-x64-gnu": {
"version": "4.1.3",
"resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-gnu/-/oxide-linux-x64-gnu-4.1.3.tgz",
"integrity": "sha512-LMdTmGe/NPtGOaOfV2HuO7w07jI3cflPrVq5CXl+2O93DCewADK0uW1ORNAcfu2YxDUS035eY2W38TxrsqngxA==",
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">= 10"
}
},
"node_modules/@tailwindcss/oxide-linux-x64-musl": {
"version": "4.1.3",
"resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-musl/-/oxide-linux-x64-musl-4.1.3.tgz",
"integrity": "sha512-aalNWwIi54bbFEizwl1/XpmdDrOaCjRFQRgtbv9slWjmNPuJJTIKPHf5/XXDARc9CneW9FkSTqTbyvNecYAEGw==",
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">= 10"
}
},
"node_modules/@tailwindcss/oxide-win32-arm64-msvc": {
"version": "4.1.3",
"resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-arm64-msvc/-/oxide-win32-arm64-msvc-4.1.3.tgz",
"integrity": "sha512-PEj7XR4OGTGoboTIAdXicKuWl4EQIjKHKuR+bFy9oYN7CFZo0eu74+70O4XuERX4yjqVZGAkCdglBODlgqcCXg==",
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"win32"
],
"engines": {
"node": ">= 10"
}
},
"node_modules/@tailwindcss/oxide-win32-x64-msvc": {
"version": "4.1.3",
"resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-x64-msvc/-/oxide-win32-x64-msvc-4.1.3.tgz",
"integrity": "sha512-T8gfxECWDBENotpw3HR9SmNiHC9AOJdxs+woasRZ8Q/J4VHN0OMs7F+4yVNZ9EVN26Wv6mZbK0jv7eHYuLJLwA==",
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"win32"
],
"engines": {
"node": ">= 10"
}
},
"node_modules/@tailwindcss/postcss": {
"version": "4.1.3",
"resolved": "https://registry.npmjs.org/@tailwindcss/postcss/-/postcss-4.1.3.tgz",
"integrity": "sha512-6s5nJODm98F++QT49qn8xJKHQRamhYHfMi3X7/ltxiSQ9dyRsaFSfFkfaMsanWzf+TMYQtbk8mt5f6cCVXJwfg==",
"dev": true,
"license": "MIT",
"dependencies": {
"@alloc/quick-lru": "^5.2.0",
"@tailwindcss/node": "4.1.3",
"@tailwindcss/oxide": "4.1.3",
"postcss": "^8.4.41",
"tailwindcss": "4.1.3"
}
},
"node_modules/@tailwindcss/postcss/node_modules/tailwindcss": {
"version": "4.1.3",
"resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.1.3.tgz",
"integrity": "sha512-2Q+rw9vy1WFXu5cIxlvsabCwhU2qUwodGq03ODhLJ0jW4ek5BUtoCsnLB0qG+m8AHgEsSJcJGDSDe06FXlP74g==",
"dev": true,
"license": "MIT"
},
"node_modules/@trysound/sax": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/@trysound/sax/-/sax-0.2.0.tgz",
@ -37530,16 +37781,6 @@
"url": "https://github.com/fb55/entities?sponsor=1"
}
},
"node_modules/css-selector-tokenizer": {
"version": "0.8.0",
"resolved": "https://registry.npmjs.org/css-selector-tokenizer/-/css-selector-tokenizer-0.8.0.tgz",
"integrity": "sha512-Jd6Ig3/pe62/qe5SBPTN8h8LeUg/pT4lLgtavPf7updwwHpvFzxvOQBHYj2LZDMjUnBzgvIUSjRcf6oT5HzHFg==",
"license": "MIT",
"dependencies": {
"cssesc": "^3.0.0",
"fastparse": "^1.1.2"
}
},
"node_modules/css-tree": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.3.1.tgz",
@ -37729,15 +37970,6 @@
"integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==",
"license": "MIT"
},
"node_modules/culori": {
"version": "3.3.0",
"resolved": "https://registry.npmjs.org/culori/-/culori-3.3.0.tgz",
"integrity": "sha512-pHJg+jbuFsCjz9iclQBqyL3B2HLCBF71BwVNujUYEvCeQMvV97R59MNK3R2+jgJ3a1fcZgI9B3vYgz8lzr/BFQ==",
"license": "MIT",
"engines": {
"node": "^12.20.0 || ^14.13.1 || >=16.0.0"
}
},
"node_modules/d3-dispatch": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/d3-dispatch/-/d3-dispatch-3.0.1.tgz",
@ -37770,22 +38002,13 @@
}
},
"node_modules/daisyui": {
"version": "4.12.23",
"resolved": "https://registry.npmjs.org/daisyui/-/daisyui-4.12.23.tgz",
"integrity": "sha512-EM38duvxutJ5PD65lO/AFMpcw+9qEy6XAZrTpzp7WyaPeO/l+F/Qiq0ECHHmFNcFXh5aVoALY4MGrrxtCiaQCQ==",
"version": "5.0.19",
"resolved": "https://registry.npmjs.org/daisyui/-/daisyui-5.0.19.tgz",
"integrity": "sha512-vuxloVgdmTnGpA6CFnQyLkXuqPmusHgYZ0L5Qg1pQzAYPUMc0HM2S3brnu7xRnAUq7ZMAqyoV78Fvht7nY2svg==",
"dev": true,
"license": "MIT",
"dependencies": {
"css-selector-tokenizer": "^0.8",
"culori": "^3",
"picocolors": "^1",
"postcss-js": "^4"
},
"engines": {
"node": ">=16.9.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/daisyui"
"url": "https://github.com/saadeghi/daisyui?sponsor=1"
}
},
"node_modules/damerau-levenshtein": {
@ -38330,15 +38553,12 @@
}
},
"node_modules/detect-libc": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz",
"integrity": "sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg==",
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.3.tgz",
"integrity": "sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==",
"license": "Apache-2.0",
"bin": {
"detect-libc": "bin/detect-libc.js"
},
"engines": {
"node": ">=0.10"
"node": ">=8"
}
},
"node_modules/detect-node": {
@ -40693,12 +40913,6 @@
"fxparser": "src/cli/cli.js"
}
},
"node_modules/fastparse": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/fastparse/-/fastparse-1.1.2.tgz",
"integrity": "sha512-483XLLxTVIwWK3QTrMGRqUfUpoOs/0hbQrl2oz4J0pAcm3A3bu84wxTFqGqkJzewCLdME38xJLJAxBABfQT8sQ==",
"license": "MIT"
},
"node_modules/fastq": {
"version": "1.19.0",
"resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.0.tgz",
@ -46450,12 +46664,12 @@
}
},
"node_modules/lightningcss": {
"version": "1.29.1",
"resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.29.1.tgz",
"integrity": "sha512-FmGoeD4S05ewj+AkhTY+D+myDvXI6eL27FjHIjoyUkO/uw7WZD1fBVs0QxeYWa7E17CUHJaYX/RUGISCtcrG4Q==",
"version": "1.29.2",
"resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.29.2.tgz",
"integrity": "sha512-6b6gd/RUXKaw5keVdSEtqFVdzWnU5jMxTUjA2bVcMNPLwSQ08Sv/UodBVtETLCn7k4S1Ibxwh7k68IwLZPgKaA==",
"license": "MPL-2.0",
"dependencies": {
"detect-libc": "^1.0.3"
"detect-libc": "^2.0.3"
},
"engines": {
"node": ">= 12.0.0"
@ -46465,22 +46679,22 @@
"url": "https://opencollective.com/parcel"
},
"optionalDependencies": {
"lightningcss-darwin-arm64": "1.29.1",
"lightningcss-darwin-x64": "1.29.1",
"lightningcss-freebsd-x64": "1.29.1",
"lightningcss-linux-arm-gnueabihf": "1.29.1",
"lightningcss-linux-arm64-gnu": "1.29.1",
"lightningcss-linux-arm64-musl": "1.29.1",
"lightningcss-linux-x64-gnu": "1.29.1",
"lightningcss-linux-x64-musl": "1.29.1",
"lightningcss-win32-arm64-msvc": "1.29.1",
"lightningcss-win32-x64-msvc": "1.29.1"
"lightningcss-darwin-arm64": "1.29.2",
"lightningcss-darwin-x64": "1.29.2",
"lightningcss-freebsd-x64": "1.29.2",
"lightningcss-linux-arm-gnueabihf": "1.29.2",
"lightningcss-linux-arm64-gnu": "1.29.2",
"lightningcss-linux-arm64-musl": "1.29.2",
"lightningcss-linux-x64-gnu": "1.29.2",
"lightningcss-linux-x64-musl": "1.29.2",
"lightningcss-win32-arm64-msvc": "1.29.2",
"lightningcss-win32-x64-msvc": "1.29.2"
}
},
"node_modules/lightningcss-darwin-arm64": {
"version": "1.29.1",
"resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.29.1.tgz",
"integrity": "sha512-HtR5XJ5A0lvCqYAoSv2QdZZyoHNttBpa5EP9aNuzBQeKGfbyH5+UipLWvVzpP4Uml5ej4BYs5I9Lco9u1fECqw==",
"version": "1.29.2",
"resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.29.2.tgz",
"integrity": "sha512-cK/eMabSViKn/PG8U/a7aCorpeKLMlK0bQeNHmdb7qUnBkNPnL+oV5DjJUo0kqWsJUapZsM4jCfYItbqBDvlcA==",
"cpu": [
"arm64"
],
@ -46498,9 +46712,9 @@
}
},
"node_modules/lightningcss-darwin-x64": {
"version": "1.29.1",
"resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.29.1.tgz",
"integrity": "sha512-k33G9IzKUpHy/J/3+9MCO4e+PzaFblsgBjSGlpAaFikeBFm8B/CkO3cKU9oI4g+fjS2KlkLM/Bza9K/aw8wsNA==",
"version": "1.29.2",
"resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.29.2.tgz",
"integrity": "sha512-j5qYxamyQw4kDXX5hnnCKMf3mLlHvG44f24Qyi2965/Ycz829MYqjrVg2H8BidybHBp9kom4D7DR5VqCKDXS0w==",
"cpu": [
"x64"
],
@ -46518,9 +46732,9 @@
}
},
"node_modules/lightningcss-freebsd-x64": {
"version": "1.29.1",
"resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.29.1.tgz",
"integrity": "sha512-0SUW22fv/8kln2LnIdOCmSuXnxgxVC276W5KLTwoehiO0hxkacBxjHOL5EtHD8BAXg2BvuhsJPmVMasvby3LiQ==",
"version": "1.29.2",
"resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.29.2.tgz",
"integrity": "sha512-wDk7M2tM78Ii8ek9YjnY8MjV5f5JN2qNVO+/0BAGZRvXKtQrBC4/cn4ssQIpKIPP44YXw6gFdpUF+Ps+RGsCwg==",
"cpu": [
"x64"
],
@ -46538,9 +46752,9 @@
}
},
"node_modules/lightningcss-linux-arm-gnueabihf": {
"version": "1.29.1",
"resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.29.1.tgz",
"integrity": "sha512-sD32pFvlR0kDlqsOZmYqH/68SqUMPNj+0pucGxToXZi4XZgZmqeX/NkxNKCPsswAXU3UeYgDSpGhu05eAufjDg==",
"version": "1.29.2",
"resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.29.2.tgz",
"integrity": "sha512-IRUrOrAF2Z+KExdExe3Rz7NSTuuJ2HvCGlMKoquK5pjvo2JY4Rybr+NrKnq0U0hZnx5AnGsuFHjGnNT14w26sg==",
"cpu": [
"arm"
],
@ -46558,9 +46772,9 @@
}
},
"node_modules/lightningcss-linux-arm64-gnu": {
"version": "1.29.1",
"resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.29.1.tgz",
"integrity": "sha512-0+vClRIZ6mmJl/dxGuRsE197o1HDEeeRk6nzycSy2GofC2JsY4ifCRnvUWf/CUBQmlrvMzt6SMQNMSEu22csWQ==",
"version": "1.29.2",
"resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.29.2.tgz",
"integrity": "sha512-KKCpOlmhdjvUTX/mBuaKemp0oeDIBBLFiU5Fnqxh1/DZ4JPZi4evEH7TKoSBFOSOV3J7iEmmBaw/8dpiUvRKlQ==",
"cpu": [
"arm64"
],
@ -46578,9 +46792,9 @@
}
},
"node_modules/lightningcss-linux-arm64-musl": {
"version": "1.29.1",
"resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.29.1.tgz",
"integrity": "sha512-UKMFrG4rL/uHNgelBsDwJcBqVpzNJbzsKkbI3Ja5fg00sgQnHw/VrzUTEc4jhZ+AN2BvQYz/tkHu4vt1kLuJyw==",
"version": "1.29.2",
"resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.29.2.tgz",
"integrity": "sha512-Q64eM1bPlOOUgxFmoPUefqzY1yV3ctFPE6d/Vt7WzLW4rKTv7MyYNky+FWxRpLkNASTnKQUaiMJ87zNODIrrKQ==",
"cpu": [
"arm64"
],
@ -46598,9 +46812,9 @@
}
},
"node_modules/lightningcss-linux-x64-gnu": {
"version": "1.29.1",
"resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.29.1.tgz",
"integrity": "sha512-u1S+xdODy/eEtjADqirA774y3jLcm8RPtYztwReEXoZKdzgsHYPl0s5V52Tst+GKzqjebkULT86XMSxejzfISw==",
"version": "1.29.2",
"resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.29.2.tgz",
"integrity": "sha512-0v6idDCPG6epLXtBH/RPkHvYx74CVziHo6TMYga8O2EiQApnUPZsbR9nFNrg2cgBzk1AYqEd95TlrsL7nYABQg==",
"cpu": [
"x64"
],
@ -46618,9 +46832,9 @@
}
},
"node_modules/lightningcss-linux-x64-musl": {
"version": "1.29.1",
"resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.29.1.tgz",
"integrity": "sha512-L0Tx0DtaNUTzXv0lbGCLB/c/qEADanHbu4QdcNOXLIe1i8i22rZRpbT3gpWYsCh9aSL9zFujY/WmEXIatWvXbw==",
"version": "1.29.2",
"resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.29.2.tgz",
"integrity": "sha512-rMpz2yawkgGT8RULc5S4WiZopVMOFWjiItBT7aSfDX4NQav6M44rhn5hjtkKzB+wMTRlLLqxkeYEtQ3dd9696w==",
"cpu": [
"x64"
],
@ -46638,9 +46852,9 @@
}
},
"node_modules/lightningcss-win32-arm64-msvc": {
"version": "1.29.1",
"resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.29.1.tgz",
"integrity": "sha512-QoOVnkIEFfbW4xPi+dpdft/zAKmgLgsRHfJalEPYuJDOWf7cLQzYg0DEh8/sn737FaeMJxHZRc1oBreiwZCjog==",
"version": "1.29.2",
"resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.29.2.tgz",
"integrity": "sha512-nL7zRW6evGQqYVu/bKGK+zShyz8OVzsCotFgc7judbt6wnB2KbiKKJwBE4SGoDBQ1O94RjW4asrCjQL4i8Fhbw==",
"cpu": [
"arm64"
],
@ -46658,9 +46872,9 @@
}
},
"node_modules/lightningcss-win32-x64-msvc": {
"version": "1.29.1",
"resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.29.1.tgz",
"integrity": "sha512-NygcbThNBe4JElP+olyTI/doBNGJvLs3bFCRPdvuCcxZCcCZ71B858IHpdm7L1btZex0FvCmM17FK98Y9MRy1Q==",
"version": "1.29.2",
"resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.29.2.tgz",
"integrity": "sha512-EdIUW3B2vLuHmv7urfzMI/h2fmlnOQBk1xlsDxkN1tCWKjNFjfLhGxYk8C8mzpSfr+A6jFFIi8fU6LbQGsRWjA==",
"cpu": [
"x64"
],
@ -58329,15 +58543,6 @@
"@img/sharp-win32-x64": "0.33.5"
}
},
"node_modules/sharp/node_modules/detect-libc": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.3.tgz",
"integrity": "sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==",
"license": "Apache-2.0",
"engines": {
"node": ">=8"
}
},
"node_modules/sharp/node_modules/semver": {
"version": "7.7.1",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.7.1.tgz",
@ -70571,7 +70776,6 @@
"@mdx-js/react": "^3.0.0",
"autoprefixer": "^10.4.20",
"clsx": "^2.0.0",
"daisyui": "^4.12.23",
"lodash": "^4.17.21",
"postcss": "^8.4.47",
"prism-react-renderer": "^2.3.0",
@ -70579,12 +70783,14 @@
"react-dom": "^19.0.0",
"react-markdown": "^9.0.1",
"remark-smartypants": "^3.0.2",
"tailwindcss": "^3.4.14"
"tailwindcss": "^4.1.3"
},
"devDependencies": {
"@babel/plugin-syntax-import-attributes": "^7.25.6",
"@docusaurus/module-type-aliases": "^3.7.0",
"@docusaurus/types": "^3.7.0",
"@tailwindcss/postcss": "^4.1.3",
"daisyui": "^5.0.19",
"glob": "^11.0.0",
"gray-matter": "^4.0.3",
"yaml-loader": "^0.8.1"
@ -70665,6 +70871,12 @@
"funding": {
"url": "https://github.com/sponsors/isaacs"
}
},
"sites/org/node_modules/tailwindcss": {
"version": "4.1.3",
"resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.1.3.tgz",
"integrity": "sha512-2Q+rw9vy1WFXu5cIxlvsabCwhU2qUwodGq03ODhLJ0jW4ek5BUtoCsnLB0qG+m8AHgEsSJcJGDSDe06FXlP74g==",
"license": "MIT"
}
}
}

View file

@ -102,16 +102,16 @@ export const Apikeys = ({ Link = false }) => {
return (
<>
<div className="tw-flex tw-flex-row tw-flex-wrap tw-gap-2 tw-items-center tw-justify-between tw-mb-4">
<div className="tw:flex tw:flex-row tw:flex-wrap tw:gap-2 tw:items-center tw:justify-between tw:mb-4">
<button
className="tw-daisy-btn tw-daisy-btn-error"
className="tw:daisy-btn tw:daisy-btn-error"
onClick={removeSelectedApikeys}
disabled={count < 1}
>
<TrashIcon /> {count} API Keys
</button>
<button
className="tw-daisy-btn tw-daisy-btn-primary tw-capitalize tw-w-full md:tw-w-auto hover:tw-text-primary-content"
className="tw:daisy-btn tw:daisy-btn-primary tw:capitalize tw:w-full tw:md:w-auto tw:hover:text-primary-content"
onClick={() =>
setModal(
<ModalWrapper keepOpenOnClick>
@ -125,13 +125,13 @@ export const Apikeys = ({ Link = false }) => {
</button>
</div>
<TableWrapper>
<table className="tw-table tw-table-auto">
<thead className="tw-border tw-border-base-300 tw-border-b-2 tw-border-t-0 tw-border-x-0">
<table className="tw:table tw:table-auto">
<thead className="tw:border tw:border-base-300 tw:border-b-2 tw:border-t-0 tw:border-x-0">
<tr className="">
<th className="">
<input
type="checkbox"
className="tw-daisy-checkbox tw-daisy-checkbox-secondary"
className="tw:daisy-checkbox tw:daisy-checkbox-secondary"
onClick={toggleAll}
checked={apikeys.length === count}
/>
@ -139,13 +139,13 @@ export const Apikeys = ({ Link = false }) => {
{Object.keys(fields).map((field) => (
<th key={field}>
<button
className="tw-daisy-btn tw-daisy-btn-link tw-capitalize tw-px-0 underline tw-hover:decoration-4 tw-decoration-2 tw-text-secondary"
className="tw:daisy-btn tw:daisy-btn-link tw:capitalize tw:px-0 underline tw:hover:decoration-4 tw:decoration-2 tw:text-secondary"
onClick={() => (order === field ? setDesc(!desc) : setOrder(field))}
>
{fields[field]}{' '}
<RightIcon
stroke={3}
className={`tw-w-4 tw-h-4 ${desc ? 'tw--' : 'tw-'}rotate-90 ${order === field ? '' : 'tw-opacity-0'}`}
className={`tw:w-4 tw:h-4 ${desc ? 'tw:-' : 'tw:'}rotate-90 ${order === field ? '' : 'tw:opacity-0'}`}
/>
</button>
</th>
@ -155,23 +155,23 @@ export const Apikeys = ({ Link = false }) => {
<tbody>
{orderBy(apikeys, order, desc ? 'desc' : 'asc').map((apikey, i) => (
<tr key={i}>
<td className="tw-text-base tw-font-medium">
<td className="tw:text-base tw:font-medium">
<input
type="checkbox"
checked={selection[apikey.id] ? true : false}
className="tw-daisy-checkbox tw-daisy-checkbox-secondary"
className="tw:daisy-checkbox tw:daisy-checkbox-secondary"
onClick={() => toggle(apikey.id)}
/>
</td>
<td className="tw-text-base tw-font-medium">
<td className="tw:text-base tw:font-medium">
<Uuid uuid={apikey.id} label="Key" />
</td>
{Object.keys(fields)
.slice(1, 4)
.map((field) => (
<td key={field} className="tw-text-base tw-font-medium">
<td key={field} className="tw:text-base tw:font-medium">
<button
className="tw-daisy-btn tw-daisy-btn-link tw-text-secondary hover:tw-decoration-4"
className="tw:daisy-btn tw:daisy-btn-link tw:text-secondary tw:hover:decoration-4"
onClick={() =>
setModal(
<ModalWrapper>
@ -184,8 +184,8 @@ export const Apikeys = ({ Link = false }) => {
</button>
</td>
))}
<td className="tw-text-base tw-font-medium">{shortDate(apikey.createdAt)}</td>
<td className="tw-text-base tw-font-medium">{shortDate(apikey.expiresAt)}</td>
<td className="tw:text-base tw:font-medium">{shortDate(apikey.createdAt)}</td>
<td className="tw:text-base tw:font-medium">{shortDate(apikey.expiresAt)}</td>
</tr>
))}
</tbody>
@ -197,10 +197,10 @@ export const Apikeys = ({ Link = false }) => {
const ApiKey = ({ apikey }) => (
<>
<h2 className="tw-flex tw-flex-row tw-items-center tw-gap-2">
<h2 className="tw:flex tw:flex-row tw:items-center tw:gap-2">
API Key <Uuid uuid={apikey.id} />
</h2>
<ul className="tw-list tw-list-disc tw-ml-4">
<ul className="tw:list tw:list-disc tw:ml-4">
{Object.entries(fields).map(([key, label]) => (
<li key={key}>
{label}: <b>{apikey[key]}</b>
@ -248,7 +248,7 @@ const NewApikey = ({ onCreate = false }) => {
}
return (
<div className="tw-w-full">
<div className="tw:w-full">
<h2>New API key {apikey ? `: ${apikey.name}` : ''}</h2>
{apikey ? (
<ShowNewApikey {...{ apikey }} />
@ -269,7 +269,7 @@ const NewApikey = ({ onCreate = false }) => {
list={levels.map((l) => ({
val: l,
label: (
<div className="tw-flex tw-flex-row tw-items-center tw-w-full tw-justify-between">
<div className="tw:flex tw:flex-row tw:items-center tw:w-full tw:justify-between">
<span>{apikeyLevels[l]}</span>
<NumberCircle nr={l} color="secondary" />
</div>
@ -278,9 +278,9 @@ const NewApikey = ({ onCreate = false }) => {
current={level}
update={setLevel}
/>
<div className="tw-flex tw-flex-row tw-gap-2 tw-items-center tw-w-full tw-my-8">
<div className="tw:flex tw:flex-row tw:gap-2 tw:items-center tw:w-full tw:my-8">
<button
className="tw-daisy-btn tw-daisy-btn-primary tw-capitalize tw-w-full md:tw-w-auto"
className="tw:daisy-btn tw:daisy-btn-primary tw:capitalize tw:w-full tw:md:w-auto"
disabled={name.length < 1}
onClick={createKey}
>
@ -295,18 +295,18 @@ const NewApikey = ({ onCreate = false }) => {
const ShowNewApikey = ({ apikey }) => (
<div>
<div className="tw-flex tw-flex-row tw-flex-wrap tw-gap-2 tw-items-center tw-mb-2">
<div className="tw:flex tw:flex-row tw:flex-wrap tw:gap-2 tw:items-center tw:mb-2">
<KeyVal k="name" val={apikey.name} color="secondary" />
<KeyVal k="level" val={apikey.level} color="secondary" />
<KeyVal k="created" val={<TimeAgo iso={apikey.createdAt} />} color="secondary" />
<KeyVal k="expires" val={<TimeToGo iso={apikey.expiresAt} />} color="secondary" />
</div>
<h6 className="tw-flex tw-flex-row tw-items-center">
<h6 className="tw:flex tw:flex-row tw:items-center">
Key
<CopyToClipboardButton sup content={apikey.key} label="API key ID" />
</h6>
<pre>{apikey.key}</pre>
<h6 className="tw-flex tw-flex-row tw-items-center">
<h6 className="tw:flex tw:flex-row tw:items-center">
Secret
<CopyToClipboardButton sup content={apikey.secret} label="API key secret" />
</h6>
@ -330,7 +330,7 @@ const ExpiryPicker = ({ expires, setExpires }) => {
}
return (
<div className="tw-flex tw-flex-row tw-gap-2 tw-items-center">
<div className="tw:flex tw:flex-row tw:gap-2 tw:items-center">
<FormControl
label="Key Expiry"
labelBL={shortDate(expires)}
@ -341,7 +341,7 @@ const ExpiryPicker = ({ expires, setExpires }) => {
min="1"
max={731}
value={days}
className="tw-daisy-range tw-daisy-range-secondary tw-w-full"
className="tw:daisy-range tw:daisy-range-secondary tw:w-full"
onChange={update}
/>
</FormControl>

View file

@ -51,12 +51,12 @@ export const Avatar = ({ welcome = false, Link = false }) => {
const nextHref = '/docs/about/guide'
return (
<div className="tw-w-full">
<div className="tw:w-full">
{!welcome || img !== false ? (
<img
alt="img"
src={img || cloudflareImageUrl({ id: `uid-${account.ihash}`, variant: 'public' })}
className="tw-shadow tw-mb-4"
className="tw:shadow tw:mb-4"
/>
) : null}
<PassiveImageInput
@ -73,17 +73,17 @@ export const Avatar = ({ welcome = false, Link = false }) => {
<SaveIcon />
Save
</IconButton>
<IconButton href={nextHref} className="tw-mt-4">
<IconButton href={nextHref} className="tw:mt-4">
<RightIcon stroke={3} /> Continue
</IconButton>
{welcomeSteps[account.control].length > 0 ? (
<>
<progress
className="tw-progress tw-progress-primary tw-w-full tw-mt-12"
className="tw:progress tw:progress-primary tw:w-full tw:mt-12"
value={700 / welcomeSteps[account.control].length}
max="100"
></progress>
<span className="tw-pt-4 tw-text-sm tw-font-bold tw-opacity-50">
<span className="tw:pt-4 tw:text-sm tw:font-bold tw:opacity-50">
7 / {welcomeSteps[account.control].length}
</span>
<WelcomeIcons
@ -96,9 +96,9 @@ export const Avatar = ({ welcome = false, Link = false }) => {
</>
) : (
<>
<p className="tw-text-right">
<p className="tw:text-right">
<button
className="tw-daisy-btn tw-daisy-btn-primary tw-w-full lg:tw-w-auto mt-8"
className="tw:daisy-btn tw:daisy-btn-primary tw:w-full tw:lg:w-auto mt-8"
onClick={save}
>
<SaveIcon /> Save Avatar

View file

@ -51,12 +51,12 @@ export const Bio = ({ welcome = false, Link = false }) => {
: '/docs/about/guide'
return (
<div className="tw-w-full">
<div className="tw:w-full">
<h6>Tell people a little bit about yourself.</h6>
<MarkdownInput id="account-bio" label="Bio" update={setBio} current={bio} placeholder="Bio" />
<p className="tw-text-right">
<p className="tw:text-right">
<button
className="tw-daisy-btn tw-daisy-btn-primary tw-w-full lg:tw-w-auto tw-mt-8"
className="tw:daisy-btn tw:daisy-btn-primary tw:w-full tw:lg:w-auto tw:mt-8"
onClick={save}
>
<SaveIcon /> Save Bio
@ -65,17 +65,17 @@ export const Bio = ({ welcome = false, Link = false }) => {
{welcome ? (
<>
<IconButton href={nextHref} className="tw-mt-4">
<IconButton href={nextHref} className="tw:mt-4">
<RightIcon stroke={3} /> Continue
</IconButton>
{welcomeSteps[account.control].length > 0 ? (
<>
<progress
className="tw-daisy-progress tw-daisy-progress-primary tw-w-full tw-mt-12"
className="tw:daisy-progress tw:daisy-progress-primary tw:w-full tw:mt-12"
value={600 / welcomeSteps[account.control].length}
max="100"
></progress>
<span className="tw-pt-4 tw-text-sm tw-font-bold tw-opacity-50">
<span className="tw:pt-4 tw:text-sm tw:font-bold tw:opacity-50">
6 / {welcomeSteps[account.control].length}
</span>
<WelcomeIcons

View file

@ -88,10 +88,10 @@ export const Bookmarks = () => {
for (const type in types) perType[type] = bookmarks.filter((b) => b.type === type)
return (
<div className="tw-w-full">
<p className="tw-text-center md:tw-text-right">
<div className="tw:w-full">
<p className="tw:text-center tw:md:text-right">
<button
className="tw-daisy-btn tw-daisy-btn-primary tw-capitalize tw-w-full md:tw-w-auto hover:tw-text-primary-content hover:tw-no-underline"
className="tw:daisy-btn tw:daisy-btn-primary tw:capitalize tw:w-full tw:md:w-auto tw:hover:text-primary-content tw:hover:no-underline"
onClick={() =>
setModal(
<ModalWrapper
@ -100,7 +100,7 @@ export const Bookmarks = () => {
slideFrom="right"
keepOpenOnClick
>
<div className="tw-w-full">
<div className="tw:w-full">
<h2>New Bookmark</h2>
<NewBookmark onCreated={() => setRefresh(refresh + 1)} />
</div>
@ -114,7 +114,7 @@ export const Bookmarks = () => {
</p>
{bookmarks.length > 0 ? (
<button
className="tw-daisy-btn tw-daisy-btn-error"
className="tw:daisy-btn tw:daisy-btn-error"
onClick={removeSelectedBookmarks}
disabled={selCount < 1}
>
@ -125,18 +125,18 @@ export const Bookmarks = () => {
perType[type].length > 0 ? (
<Fragment key={type}>
<h2>{title}</h2>
<table className="tw-table tw-w-full">
<thead className="tw-border tw-border-base-300 tw-border-b-2 tw-border-t-0 tw-border-x-0">
<table className="tw:table tw:w-full">
<thead className="tw:border tw:border-base-300 tw:border-b-2 tw:border-t-0 tw:border-x-0">
<tr>
<th className="tw-text-base-300 tw-text-base tw-text-left tw-w-8">
<th className="tw:text-base-300 tw:text-base tw:text-left tw:w-8">
<input
type="checkbox"
className="tw-daisy-checkbox tw-daisy-checkbox-secondary"
className="tw:daisy-checkbox tw:daisy-checkbox-secondary"
onClick={toggleSelectAll}
checked={bookmarks.length === selCount}
/>
</th>
<th className="tw-w-1/2">Title</th>
<th className="tw:w-1/2">Title</th>
<th>Location</th>
</tr>
</thead>
@ -145,16 +145,16 @@ export const Bookmarks = () => {
.filter((bookmark) => bookmark.type === type)
.map((bookmark, i) => (
<tr key={i}>
<td className="tw-text-base tw-font-medium">
<td className="tw:text-base tw:font-medium">
<input
type="checkbox"
checked={selected[bookmark.id] ? true : false}
className="tw-daisy-checkbox tw-daisy-checkbox-secondary"
className="tw:daisy-checkbox tw:daisy-checkbox-secondary"
onClick={() => toggleSelect(bookmark.id)}
/>
</td>
<td className="tw-text-base tw-font-medium">{bookmark.title}</td>
<td className="tw-text-base tw-font-medium">
<td className="tw:text-base tw:font-medium">{bookmark.title}</td>
<td className="tw:text-base tw:font-medium">
<WebLink href={bookmark.url}>
{bookmark.url.length > 30
? bookmark.url.slice(0, 30) + '...'
@ -210,7 +210,7 @@ export const NewBookmark = ({ onCreated = false }) => {
// Render the form
return (
<div className="tw-w-full">
<div className="tw:w-full">
<StringInput
id="bookmark-title"
label="Title"
@ -229,9 +229,9 @@ export const NewBookmark = ({ onCreated = false }) => {
valid={(val) => val.length > 0}
placeholder={'https://freesewing.org/account'}
/>
<div className="tw-flex tw-flex-row tw-gap-2 tw-items-center tw-w-full tw-my-8">
<div className="tw:flex tw:flex-row tw:gap-2 tw:items-center tw:w-full tw:my-8">
<button
className="tw-daisy-btn tw-daisy-btn-primary tw-grow tw-capitalize"
className="tw:daisy-btn tw:daisy-btn-primary tw:grow tw:capitalize"
disabled={!(title.length > 0 && url.length > 0)}
onClick={createBookmark}
>
@ -256,7 +256,7 @@ export const BookmarkButton = ({ slug, type, title }) => {
return (
<button
className={`tw-daisy-btn tw-daisy-btn-secondary tw-daisy-btn-outline ${horFlexClasses}`}
className={`tw:daisy-btn tw:daisy-btn-secondary tw:daisy-btn-outline ${horFlexClasses}`}
onClick={() =>
setModal(
<ModalWrapper flex="col" justify="top lg:justify-center" slideFrom="right">
@ -305,10 +305,10 @@ export const CreateBookmark = ({ type, title, slug }) => {
}
return (
<div className="tw-mt-12">
<div className="tw:mt-12">
<h2>New bookmark</h2>
<StringInput label="Title" current={name} update={setName} valid={notEmpty} labelBL={url} />
<button className="tw-daisy-btn tw-daisy-btn-primary tw-w-full tw-mt-4" onClick={bookmark}>
<button className="tw:daisy-btn tw:daisy-btn-primary tw:w-full tw:mt-4" onClick={bookmark}>
Create bookmark
</button>
</div>

View file

@ -70,19 +70,19 @@ export const Compare = ({ welcome = false }) => {
: '/docs/about/guide'
return (
<div className="tw-w-full">
<div className="tw:w-full">
<ListInput
id="account-compare"
label="Are you comfortable with your measurements sets being compared?"
list={['yes', 'no'].map((val) => ({
val,
label: (
<div className="tw-flex tw-flex-row tw-items-center tw-w-full tw-justify-between">
<div className="tw:flex tw:flex-row tw:items-center tw:w-full tw:justify-between">
<span>{strings[val].title}</span>
{val === 'yes' ? (
<OkIcon className="tw-w-8 h-8 tw-text-success" stroke={4} />
<OkIcon className="tw:w-8 h-8 tw:text-success" stroke={4} />
) : (
<NoIcon className="tw-w-8 h-8 tw-text-error" stroke={3} />
<NoIcon className="tw:w-8 h-8 tw:text-error" stroke={3} />
)}
</div>
),
@ -93,17 +93,17 @@ export const Compare = ({ welcome = false }) => {
/>
{welcome ? (
<>
<IconButton href={nextHref} className="tw-mt-4">
<IconButton href={nextHref} className="tw:mt-4">
<RightIcon stroke={3} /> Continue
</IconButton>
{welcomeSteps[account?.control].length > 0 ? (
<>
<progress
className="tw-daisy-progress tw-daisy-progress-primary tw-w-full tw-mt-12"
className="tw:daisy-progress tw:daisy-progress-primary tw:w-full tw:mt-12"
value={400 / welcomeSteps[account?.control].length}
max="100"
></progress>
<span className="tw-pt-4 tw-text-sm tw-font-bold tw-opacity-50">
<span className="tw:pt-4 tw:text-sm tw:font-bold tw:opacity-50">
4 / {welcomeSteps[account?.control].length}
</span>
<WelcomeIcons

View file

@ -86,16 +86,16 @@ export const Consent = ({ signUp = false, Link = false, title = false }) => {
}
return (
<div className="tw-w-full mdx">
{title ? <h2 className="tw-text-4xl">Privacy Matters</h2> : null}
<div className="tw:w-full mdx">
{title ? <h2 className="tw:text-4xl">Privacy Matters</h2> : null}
{text.intro}
<h5 className="tw-mt-8">Do you give your consent to process your account data?</h5>
<h5 className="tw:mt-8">Do you give your consent to process your account data?</h5>
{text.account}
{consent1 ? (
<Checkbox value={consent1} setter={setConsent1} label="Yes, I do" />
) : (
<button
className="tw-daisy-btn tw-daisy-btn-primary tw-daisy-btn-lg tw-w-full tw-mt-4"
className="tw:daisy-btn tw:daisy-btn-primary tw:daisy-btn-lg tw:w-full tw:mt-4"
onClick={() => setConsent1(!consent1)}
>
Click here to give your consent
@ -103,7 +103,7 @@ export const Consent = ({ signUp = false, Link = false, title = false }) => {
)}
{consent1 ? (
<>
<h5 className="tw-mt-8">
<h5 className="tw:mt-8">
Do you give your consent to share your anonymized measurements
</h5>
<Checkbox
@ -116,19 +116,19 @@ export const Consent = ({ signUp = false, Link = false, title = false }) => {
) : null}
{!consent1 && <Popout warning>This consent is required for a FreeSewing account.</Popout>}
{consent1 ? (
<button className="tw-daisy-btn tw-daisy-btn-primary tw-w-full tw-mt-4" onClick={update}>
<button className="tw:daisy-btn tw:daisy-btn-primary tw:w-full tw:mt-4" onClick={update}>
{signUp ? 'Create Account' : 'Save'}
</button>
) : signUp ? null : (
<button
className="tw-daisy-btn tw-mt-4 tw-capitalize tw-w-full tw-daisy-btn-error"
className="tw:daisy-btn tw:mt-4 tw:capitalize tw:w-full tw:daisy-btn-error"
onClick={removeAccount}
>
Remove your account
</button>
)}
<p className="tw-text-center tw-opacity-50 tw-mt-12">
<Link href="/docs/about/privacy" className="hover:tw-text-secondary tw-underline">
<p className="tw:text-center tw:opacity-50 tw:mt-12">
<Link href="/docs/about/privacy" className="tw:hover:text-secondary tw:underline">
FreeSewing Privacy Notice
</Link>
</p>
@ -138,19 +138,19 @@ export const Consent = ({ signUp = false, Link = false, title = false }) => {
const Checkbox = ({ value, setter, label, children = null }) => (
<div
className={`tw-form-control tw-p-4 hover:tw-cursor-pointer tw-rounded tw-border-l-8 tw-my-2
${value ? 'tw-border-success tw-bg-success/30' : 'tw-border-error tw-bg-error/30'}
btw-g-opacity-10 tw-shadow`}
className={`tw:form-control tw:p-4 tw:hover:cursor-pointer tw:rounded tw:border-l-8 tw:my-2
${value ? 'tw:border-success tw:bg-success/30' : 'tw:border-error tw:bg-error/30'}
btw:g-opacity-10 tw:shadow`}
onClick={() => setter(value ? false : true)}
>
<div className="tw-form-control tw-flex tw-flex-row tw-items-center tw-gap-2">
<div className="tw:form-control tw:flex tw:flex-row tw:items-center tw:gap-2">
<input
type="checkbox"
className="tw-daisy-checkbox"
className="tw:daisy-checkbox"
checked={value ? 'checked' : ''}
onChange={() => setter(value ? false : true)}
/>
<span className="tw-label-text">{label}</span>
<span className="tw:label-text">{label}</span>
</div>
{children}
</div>
@ -174,7 +174,7 @@ const text = {
</>
),
account: (
<div className="tw-border-l-4 tw-ml-1 tw-pl-4 tw-my-2 tw-opacity-80">
<div className="tw:border-l-4 tw:ml-1 tw:pl-4 tw:my-2 tw:opacity-80">
<h6>What is account data?</h6>
<p>
Your <b>email address</b>, <b>username</b>, and <b>password</b>, and any <b>measurements</b>{' '}
@ -194,7 +194,7 @@ const text = {
<p>
<b>No</b>, never.
</p>
<p className="tw-text-sm tw-italic">
<p className="tw:text-sm tw:italic">
Note: Freesewing publishes anonymized measurements as open data for scientific research. You
have the right to object to this.
</p>

View file

@ -52,14 +52,14 @@ export const Control = ({ welcome = false }) => {
: false
return (
<div className="tw-w-full">
<div className="tw:w-full">
<ListInput
id="account-control"
label="What user experience do you prefer?"
list={[1, 2, 3, 4, 5].map((val) => ({
val,
label: (
<div className="tw-flex tw-flex-row tw-items-center tw-w-full tw-justify-between">
<div className="tw:flex tw:flex-row tw:items-center tw:w-full tw:justify-between">
<span>{controlDesc[val].title}</span>
<ControlScore control={val} />
</div>
@ -71,17 +71,17 @@ export const Control = ({ welcome = false }) => {
/>
{welcome ? (
<>
<IconButton href={nextHref} className="tw-mt-4">
<IconButton href={nextHref} className="tw:mt-4">
<RightIcon stroke={3} /> Continue
</IconButton>
{welcomeSteps[control].length > 1 ? (
<>
<progress
className="tw-daisy-progress tw-daisy-progress-primary tw-w-full tw-mt-12"
className="tw:daisy-progress tw:daisy-progress-primary tw:w-full tw:mt-12"
value={100 / welcomeSteps[control].length}
max="100"
></progress>
<span className="tw-pt-4 tw-text-sm tw-font-bold tw-opacity-50">
<span className="tw:pt-4 tw:text-sm tw:font-bold tw:opacity-50">
1 / {welcomeSteps[control].length}
</span>
<WelcomeIcons done={[]} todo={welcomeSteps[control].slice(1)} current="" />

View file

@ -51,7 +51,7 @@ export const Email = ({ welcome = false, Link = false }) => {
const valid = (validateEmail(email) && validateTld(email)) || false
return (
<div className="tw-w-full">
<div className="tw:w-full">
{changed ? (
<Popout note>
<h3>Please confirm this change</h3>
@ -72,9 +72,9 @@ export const Email = ({ welcome = false, Link = false }) => {
original={account.email}
valid={() => valid}
/>
<p className="tw-text-right">
<p className="tw:text-right">
<button
className="tw-daisy-btn tw-daisy-btn-primary tw-w-full lg:tw-w-auto tw-mt-8"
className="tw:daisy-btn tw:daisy-btn-primary tw:w-full tw:lg:w-auto tw:mt-8"
onClick={save}
disabled={!valid || email.toLowerCase() === account.email}
>
@ -151,7 +151,7 @@ export const EmailChangeConfirmation = ({ onSuccess = false }) => {
return (
<>
<h1>One moment pleae</h1>
<Spinner className="tw-w-8 tw-h-8 tw-m-auto tw-animate-spin" />
<Spinner className="tw:w-8 tw:h-8 tw:m-auto tw:animate-spin" />
</>
)

View file

@ -34,11 +34,11 @@ export const Export = () => {
}
return (
<div className="tw-max-w-xl">
<div className="tw:max-w-xl">
{link ? (
<Popout link>
<h5>Your data was exported and is available for download at the following location:</h5>
<p className="tw-text-lg">
<p className="tw:text-lg">
<WebLink href={link}>{link}</WebLink>
</p>
</Popout>

View file

@ -34,7 +34,7 @@ export const Github = () => {
}
return (
<div className="tw-w-full">
<div className="tw:w-full">
<StringInput
id="account-github-email"
label="GitHub Email Address"
@ -51,9 +51,9 @@ export const Github = () => {
valid={(val) => val.length > 0}
placeholder={'joostdecock'}
/>
<p className="tw-text-right">
<p className="tw:text-right">
<button
className="tw-daisy-btn tw-daisy-btn-primary tw-w-full lg:tw-w-auto tw-mt-8"
className="tw:daisy-btn tw:daisy-btn-primary tw:w-full tw:lg:w-auto tw:mt-8"
onClick={save}
>
<SaveIcon /> Save

View file

@ -62,7 +62,7 @@ export const ImportSet = () => {
}
return (
<div className="tw-w-full">
<div className="tw:w-full">
<FileInput
label="Measurements file (YAML / JSON)"
update={uploadSet}

View file

@ -34,7 +34,7 @@ export const Instagram = () => {
}
return (
<div className="tw-w-full">
<div className="tw:w-full">
<StringInput
id="account-github-email"
label="GitHub Email Address"
@ -51,9 +51,9 @@ export const Instagram = () => {
valid={(val) => val.length > 0}
placeholder={'joostdecock'}
/>
<p className="tw-text-right">
<p className="tw:text-right">
<button
className="tw-daisy-btn tw-daisy-btn-primary tw-w-full lg:tw-w-auto tw-mt-8"
className="tw:daisy-btn tw:daisy-btn-primary tw:w-full tw:lg:w-auto tw:mt-8"
onClick={save}
>
<SaveIcon /> Save

View file

@ -72,10 +72,10 @@ const itemIcons = {
reddit: <RedditIcon />,
}
const btnClasses = 'tw-daisy-btn tw-capitalize tw-flex tw-flex-row tw-justify-between'
const btnClasses = 'tw:daisy-btn tw:capitalize tw:flex tw:flex-row tw:justify-between'
const itemClasses =
'tw-flex tw-flex-row tw-items-center tw-justify-between tw-bg-opacity-10 tw-p-2 tw-px-4 tw-rounded tw-mb-1'
const linkClasses = `hover:tw-bg-secondary hover:tw-bg-opacity-10 tw-max-w-md hover:tw-no-underline`
'tw:flex tw:flex-row tw:items-center tw:justify-between tw:p-2 tw:px-4 tw:rounded tw:mb-1'
const linkClasses = `tw:hover:bg-secondary/10 tw:max-w-md tw:hover:no-underline tw:text-base-content no-hover-decoration`
const titles = {
apikeys: 'API Keys',
@ -142,7 +142,7 @@ export const Links = ({ Link = false }) => {
img: (
<img
src={cloudflareImageUrl({ type: 'sq100', id: `uid-${account.ihash}` })}
className="tw-w-8 tw-h-8 tw-aspect-square tw-rounded-full shadow"
className="tw:w-8 tw:h-8 tw:aspect-square tw:rounded-full shadow"
/>
),
units: account.imperial ? 'Imperial' : 'Metric',
@ -158,14 +158,14 @@ export const Links = ({ Link = false }) => {
(i) => i !== 'github'
))
itemPreviews[social] = account.data[social] || (
<NoIcon className="tw-text-base-content tw-w-6 tw-h-6" stroke={2} />
<NoIcon className="tw:text-base-content tw:w-6 tw:h-6" stroke={2} />
)
return (
<div className="tw-w-full">
<div className="tw-grid tw-grid-cols-1 xl:tw-grid-cols-2 tw-gap-4 tw-mb-8">
<div className="tw:w-full">
<div className="tw:grid tw:grid-cols-1 tw:xl:grid-cols-2 tw:gap-4 tw:mb-8">
<div>
<h4 className="tw-my-2">Your Data</h4>
<h4 className="tw:my-2">Your Data</h4>
{Object.keys(controlConfig.account.fields.data).map((item) =>
controlConfig.flat[item] > control ? null : (
<Link
@ -174,11 +174,11 @@ export const Links = ({ Link = false }) => {
href={`/account/data/${item}/`}
className={`${itemClasses} ${linkClasses}`}
>
<div className="tw-flex tw-flex-row tw-items-center tw-gap-3 tw-font-medium">
<div className="tw:flex tw:flex-row tw:items-center tw:gap-3 tw:font-medium tw:text-base-content">
{itemIcons[item]}
{titles[item] ? titles[item] : capitalize(item)}
</div>
<div>{itemPreviews[item]}</div>
<div className="tw:text-base-content">{itemPreviews[item]}</div>
</Link>
)
)}
@ -186,7 +186,7 @@ export const Links = ({ Link = false }) => {
{control > 1 && (
<div>
<h4 className="tw-my-2">About You</h4>
<h4 className="tw:my-2">About You</h4>
{Object.keys(controlConfig.account.fields.info).map((item) =>
controlConfig.flat[item] > control ? null : (
<Link
@ -195,23 +195,23 @@ export const Links = ({ Link = false }) => {
href={`/account/about/${item === 'img' ? 'avatar' : item}/`}
className={`${itemClasses} ${linkClasses}`}
>
<div className="tw-flex tw-flex-row tw-items-center tw-gap-3 tw-font-medium">
<div className="tw:flex tw:flex-row tw:items-center tw:gap-3 tw:font-medium tw:text-base-content">
{itemIcons[item]}
{titles[item] ? titles[item] : capitalize(item)}
</div>
<div>{itemPreviews[item]}</div>
<div className="tw:text-base-content">{itemPreviews[item]}</div>
</Link>
)
)}
<div className={`${itemClasses} tw-opacity-60 tw-max-w-md`}>
<div className="tw-flex tw-flex-row tw-items-center tw-gap-3 tw-font-medium">
<div className={`${itemClasses} tw:opacity-60 tw:max-w-md`}>
<div className="tw:flex tw:flex-row tw:items-center tw:gap-3 tw:font-medium">
<OkIcon stroke={3} />
<span>Role</span>
</div>
<div className="tw-capitalize">{account.role}</div>
<div className="tw:capitalize">{account.role}</div>
</div>
<div className={`${itemClasses} tw-opacity-60 tw-max-w-md`}>
<div className="tw-flex tw-flex-row tw-items-center tw-gap-3 tw-font-medium">
<div className={`${itemClasses} tw:opacity-60 tw:max-w-md`}>
<div className="tw:flex tw:flex-row tw:items-center tw:gap-3 tw:font-medium">
<FingerprintIcon />
<span>ID</span>
</div>
@ -221,7 +221,7 @@ export const Links = ({ Link = false }) => {
)}
<div>
<h4 className="tw-my-2">Preferences</h4>
<h4 className="tw:my-2">Preferences</h4>
{Object.keys(controlConfig.account.fields.settings).map((item) =>
controlConfig.flat[item] > control ? null : (
<Link
@ -230,11 +230,11 @@ export const Links = ({ Link = false }) => {
href={`/account/preferences/${item}/`}
className={`${itemClasses} ${linkClasses}`}
>
<div className="tw-flex tw-flex-row tw-items-center tw-gap-3 tw-font-medium">
<div className="tw:flex tw:flex-row tw:items-center tw:gap-3 tw:font-medium tw:text-base-content">
{itemIcons[item]}
{titles[item] ? titles[item] : capitalize(item)}
</div>
<div>{itemPreviews[item]}</div>
<div className="tw:text-base-content">{itemPreviews[item]}</div>
</Link>
)
)}
@ -242,7 +242,7 @@ export const Links = ({ Link = false }) => {
{control > 2 && (
<div>
<h4 className="tw-my-2">Linked Identities</h4>
<h4 className="tw:my-2">Linked Identities</h4>
{Object.keys(controlConfig.account.fields.identities).map((item) =>
controlConfig.flat[item] > control ? null : (
<Link
@ -251,11 +251,11 @@ export const Links = ({ Link = false }) => {
href={`/account/social/${item}/`}
className={`${itemClasses} ${linkClasses}`}
>
<div className="tw-flex tw-flex-row tw-items-center tw-gap-3 tw-font-medium">
<div className="tw:flex tw:flex-row tw:items-center tw:gap-3 tw:font-medium tw:text-base-content">
{itemIcons[item]}
{titles[item] ? titles[item] : capitalize(item)}
</div>
<div>{itemPreviews[item]}</div>
<div className="tw:text-base-content">{itemPreviews[item]}</div>
</Link>
)
)}
@ -264,7 +264,7 @@ export const Links = ({ Link = false }) => {
{control > 1 && (
<div>
<h4 className="tw-my-2">Security</h4>
<h4 className="tw:my-2">Security</h4>
{Object.keys(controlConfig.account.fields.security).map((item) =>
controlConfig.flat[item] > control ? null : (
<Link
@ -273,11 +273,11 @@ export const Links = ({ Link = false }) => {
href={`/account/security/${item}/`}
className={`${itemClasses} ${linkClasses}`}
>
<div className="tw-flex tw-flex-row tw-items-center tw-gap-3 tw-font-medium">
<div className="tw:flex tw:flex-row tw:items-center tw:gap-3 tw:font-medium tw:text-base-content">
{itemIcons[item]}
{titles[item] ? titles[item] : capitalize(item)}
</div>
<div>{itemPreviews[item]}</div>
<div className="tw:text-base-content">{itemPreviews[item]}</div>
</Link>
)
)}
@ -286,15 +286,15 @@ export const Links = ({ Link = false }) => {
{control > 1 && (
<div>
<h4 className="tw-my-2">Actions</h4>
<h4 className="tw:my-2">Actions</h4>
{control > 2 && (
<Link
className={`${itemClasses} ${linkClasses}`}
title="Import data"
href="/account/actions/import/"
>
<UploadIcon />
<span className="tw-font-medium">Import data</span>
<UploadIcon className="tw:w-6 tw:h-6 tw:text-base-content" />
<span className="tw:font-medium tw:text-base-content">Import data</span>
</Link>
)}
{control > 2 && (
@ -303,8 +303,8 @@ export const Links = ({ Link = false }) => {
title="Export your data"
href="/account/actions/export/"
>
<DownloadIcon />
<span className="tw-font-medium">Export your data</span>
<DownloadIcon className="tw:w-6 tw:h-6 tw:text-base-content" />
<span className="tw:font-medium tw:text-base-content">Export your data</span>
</Link>
)}
{control > 2 && (
@ -313,8 +313,8 @@ export const Links = ({ Link = false }) => {
title="Reload account data"
href="/account/actions/reload/"
>
<ReloadIcon />
<span className="tw-font-medium">Reload account data</span>
<ReloadIcon className="tw:w-6 tw:h-6 tw:text-base-content" />
<span className="tw:font-medium tw:text-base-content">Reload account data</span>
</Link>
)}
{control > 3 && (
@ -323,8 +323,10 @@ export const Links = ({ Link = false }) => {
title="Restrict processing of your data"
href="/account/actions/restrict/"
>
<CloseIcon className="tw-w-6 tw-h-6 tw-text-warning" stroke={3} />
<span className="tw-font-medium">Restrict processing of your data</span>
<CloseIcon className="tw:w-6 tw:h-6 tw:text-warning" stroke={3} />
<span className="tw:font-medium tw:text-base-content">
Restrict processing of your data
</span>
</Link>
)}
<Link
@ -332,28 +334,31 @@ export const Links = ({ Link = false }) => {
title="Remove your account"
href="/account/actions/remove/"
>
<TrashIcon className="tw-w-6 tw-h-6 tw-text-warning" />
<span className="tw-font-medium">Remove your account</span>
<TrashIcon className="tw:w-6 tw:h-6 tw:text-warning" />
<span className="tw:font-medium tw:text-base-content">Remove your account</span>
</Link>
</div>
)}
</div>
<div className="tw-flex tw-flex-row tw-flex-wrap tw-gap-2 md:tw-gap-4 tw-justify-end">
<div className="tw:flex tw:flex-row tw:flex-wrap tw:gap-2 tw:md:gap-4 tw:justify-end">
{account.role === 'admin' && (
<Link className={`${btnClasses} tw-daisy-btn-accent md:tw-w-64`} href="/admin">
<WrenchIcon />
Administration
<Link
className={`${btnClasses} tw:daisy-btn-accent tw:md:w-64 tw:text-accent-content`}
href="/admin"
>
<WrenchIcon className="tw:w-6 tw:h-6 tw:text-accent-content" />
<span className="tw:text-accent-content">Administration</span>
</Link>
)}
{control > 1 && (
<Link className={`${btnClasses} tw-daisy-btn-secondary md:tw-w-64`} href="/profile">
<UserIcon />
Your Profile
<Link className={`${btnClasses} tw:daisy-btn-secondary tw:md:w-64`} href="/profile">
<UserIcon className="tw:w-6 tw:h-6 tw:text-accent-content" />
<span className="tw:text-accent-content">Your Profile</span>
</Link>
)}
<button
className={`${btnClasses} tw-daisy-btn-neutral md:tw-w-64`}
className={`${btnClasses} tw:daisy-btn-neutral tw:md:w-64`}
onClick={() => signOut()}
>
<SignoutIcon />

View file

@ -89,14 +89,14 @@ export const Mfa = ({ welcome = false, title = true }) => {
if (enable) titleText = 'Set up Multi-Factor Authentication'
return (
<div className="tw-w-full">
<div className="tw:w-full">
{title ? <h2>{titleText}</h2> : null}
{enable ? (
<>
<div className="tw-flex tw-flex-row tw-items-center tw-justify-center tw-px-8 lg:tw-px-36">
<div className="tw:flex tw:flex-row tw:items-center tw:justify-center tw:px-8 tw:lg:px-36">
<div dangerouslySetInnerHTML={{ __html: enable.qrcode }} />
</div>
<p className="tw-flex tw-flex-row tw-items-center tw-justify-center">{enable.secret}</p>
<p className="tw:flex tw:flex-row tw:items-center tw:justify-center">{enable.secret}</p>
<Bullet num="1">
Add FreeSewing to your Authenticator App by scanning the QR code above. If you cannot
scan the QR code, you can manually enter the secret below it.
@ -107,14 +107,14 @@ export const Mfa = ({ welcome = false, title = true }) => {
<input
value={code}
onChange={(evt) => setCode(evt.target.value)}
className="tw-daisy-input tw-w-64 tw-m-auto tw-text-4xl tw-daisy-input-bordered tw-daisy-input-lg tw-flex tw-flex-row tw-text-center tw-mb-8 tw-tracking-widest"
className="tw:daisy-input tw:w-64 tw:m-auto tw:text-4xl tw:daisy-input-bordered tw:daisy-input-lg tw:flex tw:flex-row tw:text-center tw:mb-8 tw:tracking-widest"
type="text"
inputMode="numeric"
pattern="[0-9]{6}"
placeholder="000000"
/>
<button
className={`${horFlexClasses} tw-daisy-btn tw-daisy-btn-success tw-daisy-btn-lg tw-block tw-w-full md:tw-w-auto tw-mx-auto`}
className={`${horFlexClasses} tw:daisy-btn tw:daisy-btn-success tw:daisy-btn-lg tw:block tw:w-full tw:md:w-auto tw:mx-auto`}
onClick={confirmMfa}
>
<LockIcon />
@ -123,7 +123,7 @@ export const Mfa = ({ welcome = false, title = true }) => {
</>
) : null}
{disable ? (
<div className="tw-my-8 tw-max-w-xl">
<div className="tw:my-8 tw:max-w-xl">
<Bullet num="1">
<h5>Please enter your password to confirm this action</h5>
<PasswordInput
@ -138,13 +138,13 @@ export const Mfa = ({ welcome = false, title = true }) => {
<input
value={code}
onChange={(evt) => setCode(evt.target.value)}
className="tw-input tw-w-full tw-text-4xl tw-input-bordered tw-input-lg tw-flex tw-flex-row tw-text-center tw-mb-8 tw-tracking-widest"
className="tw:input tw:w-full tw:text-4xl tw:input-bordered tw:input-lg tw:flex tw:flex-row tw:text-center tw:mb-8 tw:tracking-widest"
type="text"
placeholder={'000000'}
/>
</Bullet>
<button
className={`${horFlexClasses} tw-daisy-btn tw-daisy-btn-error tw-daisy-btn-lg`}
className={`${horFlexClasses} tw:daisy-btn tw:daisy-btn-error tw:daisy-btn-lg`}
onClick={disableMfa}
disabled={code.length < 4 || password.length < 3}
>
@ -163,8 +163,8 @@ export const Mfa = ({ welcome = false, title = true }) => {
You can use each of these codes only once. Write them down, because this is the only
time you will get to see them.
</p>
<div className="hljs tw-my-4">
<div className="tw-flex tw-flex-row tw-justify-between tw-items-center tw-text-xs tw-font-medium tw-text-warning tw-mt-1 tw-border-b tw-border-neutral-content tw-border-opacity-25 tw-px-4 tw-py-1 tw-mb-2 lg:tw-text-sm">
<div className="hljs tw:my-4">
<div className="tw:flex tw:flex-row tw:justify-between tw:items-center tw:text-xs tw:font-medium tw:text-warning tw:mt-1 tw:border-b tw:border-neutral-content tw:border-opacity-25 tw:px-4 tw:py-1 tw:mb-2 tw:lg:text-sm">
<span>MFA Scratch Codes</span>
<CopyToClipboardButton
content={
@ -173,17 +173,17 @@ export const Mfa = ({ welcome = false, title = true }) => {
}
/>
</div>
<pre className="language-shell hljs tw-text-base lg:tw-text-lg tw-whitespace-break-spaces tw-overflow-scroll tw-pr-4">
<pre className="language-shell hljs tw:text-base tw:lg:text-lg tw:whitespace-break-spaces tw:overflow-scroll tw:pr-4">
{scratchCodes.map((code) => code + '\n')}
</pre>
</div>
</>
) : (
<div className="tw-mt-4">
<div className="tw:mt-4">
{account.mfaEnabled ? (
disable ? null : (
<button
className={`${horFlexClasses} tw-daisy-btn tw-daisy-btn-primary tw-w-full md:tw-w-auto tw-daisy-btn-outline`}
className={`${horFlexClasses} tw:daisy-btn tw:daisy-btn-primary tw:w-full tw:md:w-auto tw:daisy-btn-outline`}
onClick={() => setDisable(true)}
>
<NoIcon stroke={3} />
@ -193,7 +193,7 @@ export const Mfa = ({ welcome = false, title = true }) => {
) : enable ? null : (
<div>
<button
className={`${horFlexClasses} tw-daisy-btn tw-daisy-btn-primary tw-w-full md:tw-w-auto tw-daisy-btn-lg`}
className={`${horFlexClasses} tw:daisy-btn tw:daisy-btn-primary tw:w-full tw:md:w-auto tw:daisy-btn-lg`}
onClick={enableMfa}
>
<LockIcon />
@ -215,10 +215,10 @@ export const Mfa = ({ welcome = false, title = true }) => {
}
const Bullet = ({ num, children }) => (
<div className="tw-flex tw-flex-row tw-items-start tw-py-4 tw-w-full tw-gap-4">
<span className="tw-bg-secondary tw-text-secondary-content tw-rounded-full tw-w-8 tw-h-8 tw-p-1 tw-inline-block tw-text-center tw-font-bold tw-mr-4 tw-shrink-0">
<div className="tw:flex tw:flex-row tw:items-start tw:py-4 tw:w-full tw:gap-4">
<span className="tw:bg-secondary tw:text-secondary-content tw:rounded-full tw:w-8 tw:h-8 tw:p-1 tw:inline-block tw:text-center tw:font-bold tw:mr-4 tw:shrink-0">
{num}
</span>
<div className="tw-text-lg tw-grow">{children}</div>
<div className="tw:text-lg tw:grow">{children}</div>
</div>
)

View file

@ -58,21 +58,21 @@ export const Newsletter = ({ welcome = false, Link = false }) => {
: '/docs/about/guide'
return (
<div className="tw-w-full">
<div className="tw:w-full">
<ListInput
id="account-newsletter"
label="Would you like to receive the FreeSewing newsletter?"
list={['yes', 'no'].map((val) => ({
val,
label: (
<div className="tw-flex tw-flex-row tw-items-center tw-w-full tw-justify-between">
<div className="tw:flex tw:flex-row tw:items-center tw:w-full tw:justify-between">
<span>
{val === 'yes' ? 'Yes, I would like to receive the newsletter' : 'No thanks'}
</span>
{val === 'yes' ? (
<OkIcon className="tw-w-8 tw-h-8 tw-text-success" stroke={4} />
<OkIcon className="tw:w-8 tw:h-8 tw:text-success" stroke={4} />
) : (
<NoIcon className="tw-w-8 tw-h-8 tw-text-error" stroke={3} />
<NoIcon className="tw:w-8 tw:h-8 tw:text-error" stroke={3} />
)}
</div>
),
@ -86,17 +86,17 @@ export const Newsletter = ({ welcome = false, Link = false }) => {
/>
{welcome ? (
<>
<IconButton href={nextHref} className="tw-mt-4">
<IconButton href={nextHref} className="tw:mt-4">
<RightIcon stroke={3} /> Continue
</IconButton>
{welcomeSteps[account?.control].length > 0 ? (
<>
<progress
className="tw-daisy-progress tw-daisy-progress-primary tw-w-full tw-mt-12"
className="tw:daisy-progress tw:daisy-progress-primary tw:w-full tw:mt-12"
value={200 / welcomeSteps[account?.control].length}
max="100"
></progress>
<span className="tw-pt-4 tw-text-sm tw-font-bold tw-opacity-50">
<span className="tw:pt-4 tw:text-sm tw:font-bold tw:opacity-50">
2 / {welcomeSteps[account?.control].length}
</span>
<WelcomeIcons
@ -120,7 +120,7 @@ export const Newsletter = ({ welcome = false, Link = false }) => {
Unsubscribe link
</Link>
</p>
<p className="tw-text-sm">
<p className="tw:text-sm">
This link is to unsubscribe you specifically, do not share it with other subscribers.
</p>
</Popout>

View file

@ -43,7 +43,7 @@ export const Password = ({ welcome = false, Link = false }) => {
}
return (
<div className="tw-w-full">
<div className="tw:w-full">
<PasswordInput
id="account-password"
label="Something only you know"
@ -53,7 +53,7 @@ export const Password = ({ welcome = false, Link = false }) => {
placeholder="Tip: use a password manager"
/>
<button
className={`tw-flex tw-flex-row tw-gap-2 tw-items-center tw-daisy-btn tw-justify-between tw-daisy-btn-primary tw-w-full md:tw-w-auto tw-w-full`}
className={`tw:flex tw:flex-row tw:gap-2 tw:items-center tw:daisy-btn tw:justify-between tw:daisy-btn-primary tw:w-full tw:md:w-auto tw:w-full`}
onClick={save}
disabled={password.length < 4}
>
@ -66,9 +66,9 @@ export const Password = ({ welcome = false, Link = false }) => {
We do not enforce a password policy, but we do recommend you enable Two-Factor
Authentication to keep your FreeSewing account safe.
</p>
<p className="tw-text-right tw-m-0 tw-pt-0">
<Link className="tw-daisy-btn tw-daisy-btn-accent" href="/account/mfa">
Two-Factor Authentication <RightIcon className="tw-h-6 tw-w-6 tw-ml-2" />
<p className="tw:text-right tw:m-0 tw:pt-0">
<Link className="tw:daisy-btn tw:daisy-btn-accent" href="/account/mfa">
Two-Factor Authentication <RightIcon className="tw:h-6 tw:w-6 tw:ml-2" />
</Link>
</p>
</Popout>

View file

@ -135,7 +135,7 @@ export const Pattern = ({ id, Link }) => {
if (!edit)
return (
<div className="tw-w-full">
<div className="tw:w-full">
{pattern.public ? (
<Popout note>
<h5>This is the private view of your pattern</h5>
@ -144,9 +144,9 @@ export const Pattern = ({ id, Link }) => {
<br />
But only you can access this private view.
</p>
<p className="tw-text-right">
<p className="tw:text-right">
<Link
className={`tw-daisy-btn tw-daisy-btn-secondary hover:tw-text-secondary-content hover:tw-no-underline`}
className={`tw:daisy-btn tw:daisy-btn-secondary tw:hover:text-secondary-content tw:hover:no-underline`}
href={`/pattern?id=${pattern.id}`}
>
<PatternIcon />
@ -166,7 +166,7 @@ export const Pattern = ({ id, Link }) => {
)
return (
<div className="tw-w-full">
<div className="tw:w-full">
<h2>Edit pattern {pattern.name}</h2>
{/* Name is always shown */}
@ -204,10 +204,10 @@ export const Pattern = ({ id, Link }) => {
{
val: true,
label: (
<div className="tw-flex tw-flex-row tw-items-center tw-flex-wrap tw-justify-between tw-w-full">
<div className="tw:flex tw:flex-row tw:items-center tw:flex-wrap tw:justify-between tw:w-full">
<span>Public Pattern</span>
<OkIcon
className="tw-w-8 tw-h-8 tw-text-success tw-bg-base-100 tw-rounded-full tw-p-1"
className="tw:w-8 tw:h-8 tw:text-success tw:bg-base-100 tw:rounded-full tw:p-1"
stroke={4}
/>
</div>
@ -217,10 +217,10 @@ export const Pattern = ({ id, Link }) => {
{
val: false,
label: (
<div className="tw-flex tw-flex-row tw-items-center tw-flex-wrap tw-justify-between tw-w-full">
<div className="tw:flex tw:flex-row tw:items-center tw:flex-wrap tw:justify-between tw:w-full">
<span>Private Pattern</span>
<NoIcon
className="tw-w-8 tw-h-8 tw-text-error tw-bg-base-100 tw-rounded-full tw-p-1"
className="tw:w-8 tw:h-8 tw:text-error tw:bg-base-100 tw:rounded-full tw:p-1"
stroke={3}
/>
</div>
@ -237,15 +237,15 @@ export const Pattern = ({ id, Link }) => {
{account.control >= controlConfig.account.patterns.notes ? (
<MarkdownInput id="pattern-notes" label="Notes" update={setNotes} current={notes} />
) : null}
<div className="tw-flex tw-flex-row tw-items-center tw-align-end tw-gap-2 tw-mt-8">
<div className="tw:flex tw:flex-row tw:items-center tw:align-end tw:gap-2 tw:mt-8">
<button
onClick={() => setEdit(false)}
className={`tw-daisy-btn tw-daisy-btn-primary tw-daisy-btn-outline`}
className={`tw:daisy-btn tw:daisy-btn-primary tw:daisy-btn-outline`}
>
<ResetIcon />
Cancel
</button>
<button onClick={save} className="tw-daisy-btn tw-daisy-btn-primary tw-grow">
<button onClick={save} className="tw:daisy-btn tw:daisy-btn-primary tw:grow">
<UploadIcon />
Save Pattern
</button>
@ -272,7 +272,7 @@ export const PatternCard = ({
const s = sizes[size]
const wrapperProps = {
className: `tw-bg-base-300 tw-w-full tw-mb-2 tw-mx-auto tw-flex tw-flex-col tw-items-start tw-text-center tw-justify-center tw-rounded tw-shadow tw-py-4 tw-w-${s} tw-aspect-square`,
className: `tw:bg-base-300 tw:w-full tw:mb-2 tw:mx-auto tw:flex tw:flex-col tw:items-start tw:text-center tw:justify-center tw:rounded tw:shadow tw:py-4 tw:w-${s} tw:aspect-square`,
style: {
backgroundImage: `url(${cloudflareImageUrl({ type: 'w1000', id: pattern.img })})`,
backgroundSize: 'cover',
@ -315,7 +315,7 @@ export const PatternCard = ({
const BadgeLink = ({ label, href }) => (
<a
href={href}
className="tw-daisy-badge tw-daisy-badge-secondary tw-font-bold tw-daisy-badge-lg hover:tw-text-secondary-content hover:tw-no-underline"
className="tw:daisy-badge tw:daisy-badge-secondary tw:font-bold tw:daisy-badge-lg tw:hover:text-secondary-content tw:hover:no-underline"
>
{label}
</a>
@ -336,19 +336,19 @@ const PatternHeader = ({
}) => (
<>
<h2>{pattern.name}</h2>
<div className="tw-flex tw-flex-row tw-flex-wrap tw-gap-2 tw-text-sm tw-items-center tw-mb-2">
<div className="tw:flex tw:flex-row tw:flex-wrap tw:gap-2 tw:text-sm tw:items-center tw:mb-2">
<KeyVal k="ID" val={pattern.id} color="secondary" />
<KeyVal k="Created" val={<TimeAgo iso={pattern.createdAt} />} color="secondary" />
<KeyVal k="Updated" val={<TimeAgo iso={pattern.updatedAt} />} color="secondary" />
<KeyVal k="Public" val={pattern.public ? 'yes' : 'no'} color="secondary" />
</div>
<div className="tw-flex tw-flex-wrap md:tw-flex-nowrap tw-flex-row tw-gap-2 tw-w-full">
<div className="tw-w-full md:tw-w-96 tw-shrink-0">
<div className="tw:flex tw:flex-wrap tw:md:flex-nowrap tw:flex-row tw:gap-2 tw:w-full">
<div className="tw:w-full tw:md:w-96 tw:shrink-0">
<PatternCard pattern={pattern} size="md" Link={Link} />
</div>
<div className="tw-flex tw-flex-col tw-justify-end tw-gap-2 tw-mb-2 tw-grow">
<div className="tw:flex tw:flex-col tw:justify-end tw:gap-2 tw:mb-2 tw:grow">
{account.control > 3 && (pattern?.public || pattern.userId === account.id) ? (
<div className="tw-flex tw-flex-row tw-gap-2 tw-items-center">
<div className="tw:flex tw:flex-row tw:gap-2 tw:items-center">
<BadgeLink label="JSON" href={`${urls.backend}/patterns/${pattern.id}.json`} />
<BadgeLink label="YAML" href={`${urls.backend}/patterns/${pattern.id}.yaml`} />
</div>
@ -358,12 +358,12 @@ const PatternHeader = ({
<button
onClick={() =>
setModal(
<ModalWrapper flex="col" justify="top lg:tw-justify-center" slideFrom="right">
<ModalWrapper flex="col" justify="top tw:lg:justify-center" slideFrom="right">
<img src={cloudflareImageUrl({ type: 'public', id: pattern.img })} />
</ModalWrapper>
)
}
className={`tw-daisy-btn tw-daisy-btn-secondary tw-daisy-btn-outline ${horFlexClasses}`}
className={`tw:daisy-btn tw:daisy-btn-secondary tw:daisy-btn-outline ${horFlexClasses}`}
>
<ShowcaseIcon />
Show Image
@ -371,7 +371,7 @@ const PatternHeader = ({
{account.control > 3 ? (
<button
onClick={() => togglePublic()}
className={`tw-daisy-btn tw-daisy-btn-${pattern.public ? 'error' : 'success'} tw-daisy-btn-outline ${horFlexClasses} hover:tw-text-${pattern.public ? 'error' : 'success'}-content`}
className={`tw:daisy-btn tw:daisy-btn-${pattern.public ? 'error' : 'success'} tw:daisy-btn-outline ${horFlexClasses} hover:tw:text-${pattern.public ? 'error' : 'success'}-content`}
>
{pattern.public ? <BoolNoIcon /> : <BoolYesIcon />}
Make pattern {pattern.public ? 'private' : 'public'}
@ -381,19 +381,19 @@ const PatternHeader = ({
<>
<Link
href={patternUrlFromState(pattern, true)}
className={`tw-daisy-btn tw-daisy-btn-primary tw-daisy-btn-outline ${horFlexClasses}`}
className={`tw:daisy-btn tw:daisy-btn-primary tw:daisy-btn-outline ${horFlexClasses}`}
>
<FreeSewingIcon /> Update Pattern
</Link>
<button
className={`tw-daisy-btn tw-daisy-btn-primary tw-daisy-btn-outline ${horFlexClasses}`}
className={`tw:daisy-btn tw:daisy-btn-primary tw:daisy-btn-outline ${horFlexClasses}`}
onClick={clone}
>
<CloneIcon /> Clone Pattern
</button>
<button
onClick={() => setEdit(true)}
className={`tw-daisy-btn tw-daisy-btn-primary ${horFlexClasses}`}
className={`tw:daisy-btn tw:daisy-btn-primary ${horFlexClasses}`}
>
<EditIcon /> Edit Pattern Metadata
</button>

View file

@ -89,16 +89,16 @@ export const Patterns = ({ Link = false }) => {
return (
<>
<div className="tw-flex tw-flex-row tw-flex-wrap tw-gap-2 tw-items-center tw-justify-between tw-mb-4">
<div className="tw:flex tw:flex-row tw:flex-wrap tw:gap-2 tw:items-center tw:justify-between tw:mb-4">
<button
className="tw-daisy-btn tw-daisy-btn-error"
className="tw:daisy-btn tw:daisy-btn-error"
onClick={removeSelectedPatterns}
disabled={count < 1}
>
<TrashIcon /> {count} {t('patterns')}
</button>
<Link
className="tw-daisy-btn tw-daisy-btn-primary tw-capitalize tw-w-full md:tw-w-auto hover:tw-text-primary-content"
className="tw:daisy-btn tw:daisy-btn-primary tw:capitalize tw:w-full tw:md:w-auto tw:hover:text-primary-content"
href="/editor/"
>
<PlusIcon />
@ -106,13 +106,13 @@ export const Patterns = ({ Link = false }) => {
</Link>
</div>
<TableWrapper>
<table className="tw-table tw-table-auto">
<thead className="tw-border tw-border-base-300 tw-border-b-2 tw-border-t-0 tw-border-x-0">
<table className="tw:table tw:table-auto">
<thead className="tw:border tw:border-base-300 tw:border-b-2 tw:border-t-0 tw:border-x-0">
<tr className="">
<th className="">
<input
type="checkbox"
className="tw-daisy-checkbox tw-daisy-checkbox-secondary"
className="tw:daisy-checkbox tw:daisy-checkbox-secondary"
onClick={toggleAll}
checked={patterns.length === count}
/>
@ -120,13 +120,13 @@ export const Patterns = ({ Link = false }) => {
{Object.keys(fields).map((field) => (
<th key={field}>
<button
className="tw-daisy-btn tw-daisy-btn-link tw-capitalize tw-px-0 tw-underline hover:tw-decoration-4 tw-decoration-2 tw-text-secondary"
className="tw:daisy-btn tw:daisy-btn-link tw:capitalize tw:px-0 tw:underline tw:hover:decoration-4 tw:decoration-2 tw:text-secondary"
onClick={() => (order === field ? setDesc(!desc) : setOrder(field))}
>
{fields[field]}{' '}
<RightIcon
stroke={3}
className={`tw-w-4 tw-h-4 ${desc ? 'tw--' : 'tw-'}rotate-90 ${order === field ? '' : 'tw-opacity-0'}`}
className={`tw:w-4 tw:h-4 ${desc ? 'tw:-' : 'tw:'}rotate-90 ${order === field ? '' : 'tw:opacity-0'}`}
/>
</button>
</th>
@ -136,16 +136,16 @@ export const Patterns = ({ Link = false }) => {
<tbody>
{orderBy(patterns, order, desc ? 'desc' : 'asc').map((pattern, i) => (
<tr key={i}>
<td className="tw-text-base tw-font-medium">
<td className="tw:text-base tw:font-medium">
<input
type="checkbox"
checked={selection[pattern.id] ? true : false}
className="tw-daisy-checkbox tw-daisy-checkbox-secondary"
className="tw:daisy-checkbox tw:daisy-checkbox-secondary"
onClick={() => toggle(pattern.id)}
/>
</td>
<td className="tw-text-base tw-font-medium">{pattern.id}</td>
<td className="tw-text-base tw-font-medium">
<td className="tw:text-base tw:font-medium">{pattern.id}</td>
<td className="tw:text-base tw:font-medium">
<PatternCard
href={`/account/data/patterns/pattern?id=${pattern.id}`}
pattern={pattern}
@ -153,24 +153,24 @@ export const Patterns = ({ Link = false }) => {
Link={Link}
/>
</td>
<td className="tw-text-base tw-font-medium">
<td className="tw:text-base tw:font-medium">
<Link
href={`/account/data/patterns/pattern?id=${pattern.id}`}
className="tw-text-secondary tw-underline tw-decoration-2 hover:tw-decoration-4"
className="tw:text-secondary tw:underline tw:decoration-2 tw:hover:decoration-4"
>
{pattern.name}
</Link>
</td>
<td className="tw-text-base tw-font-medium">
<td className="tw:text-base tw:font-medium">
<Link
href={`/designs/${pattern.design}`}
className="tw-text-secondary tw-underline tw-decoration-2 hover:tw-decoration-4"
className="tw:text-secondary tw:underline tw:decoration-2 tw:hover:decoration-4"
>
{capitalize(pattern.design)}
</Link>
</td>
<td className="tw-text-base tw-font-medium">{shortDate(pattern.createdAt)}</td>
<td className="tw-text-base tw-font-medium">
<td className="tw:text-base tw:font-medium">{shortDate(pattern.createdAt)}</td>
<td className="tw:text-base tw:font-medium">
{pattern.public ? <BoolYesIcon /> : <BoolNoIcon />}
</td>
</tr>

View file

@ -56,7 +56,7 @@ const Platform = ({ platform = false }) => {
}
return (
<div className="tw-w-full">
<div className="tw:w-full">
<StringInput
id={`account-${platform}`}
label={platform === 'website' ? `Website URL` : `${labels[platform]} account`}
@ -65,9 +65,9 @@ const Platform = ({ platform = false }) => {
valid={(val) => val.length > 0}
placeholder={'joostdecock'}
/>
<p className="tw-text-right">
<p className="tw:text-right">
<button
className="tw-daisy-btn tw-daisy-btn-primary tw-w-full lg:tw-w-auto tw-mt-8"
className="tw:daisy-btn tw:daisy-btn-primary tw:w-full tw:lg:w-auto tw:mt-8"
onClick={save}
>
<SaveIcon /> Save

View file

@ -32,7 +32,7 @@ export const Reload = () => {
}
return (
<div className="tw-w-full">
<div className="tw:w-full">
<p>
The data stored in your browser can sometimes get out of sync with the data stored in our
backend.

View file

@ -48,22 +48,22 @@ export const Remove = () => {
)
return (
<div className="tw-w-full">
<div className="tw:w-full">
<IconButton
onClick={() =>
setModal(
<ModalWrapper keepOpenOnClick>
<div className="tw-text-center tw-w-full">
<div className="tw:text-center tw:w-full">
<h2>There is no way back from this</h2>
<p>If this is what you want, then go ahead.</p>
<IconButton onClick={removeAccount} color="error" className="tw-mx-auto">
<IconButton onClick={removeAccount} color="error" className="tw:mx-auto">
<TrashIcon />
Remove your FreeSewing account
</IconButton>
<IconButton
onClick={clearModal}
color="primary"
className="tw-mx-auto tw-daisy-btn-outline tw-mt-4"
className="tw:mx-auto tw:daisy-btn-outline tw:mt-4"
>
<ExitIcon />
Back to safety

View file

@ -53,7 +53,7 @@ export const Restrict = ({ Link = false }) => {
)
return (
<div className="tw-w-full">
<div className="tw:w-full">
<p>
The GDPR guarantees{' '}
<Link href="/docs/about/rights/#the-right-to-restrict-processing" className={linkClasses}>
@ -66,21 +66,21 @@ export const Restrict = ({ Link = false }) => {
onClick={() =>
setModal(
<ModalWrapper keepOpenOnClick>
<div className="tw-text-center tw-w-full tw-max-w-xl">
<div className="tw:text-center tw:w-full tw:max-w-xl">
<h2>Proceed with caution</h2>
<p>
While no data will be removed, this will disable your account. Furthermore, you
can not undo this on your own, but will have to contact support when you want to
restore access to your account.
</p>
<IconButton onClick={restrictAccount} color="error" className="tw-mx-auto">
<IconButton onClick={restrictAccount} color="error" className="tw:mx-auto">
<NoIcon stroke={3} />
Restrict processing of your FreeSewing data
</IconButton>
<IconButton
onClick={clearModal}
color="primary"
className="tw-mx-auto tw-daisy-btn-outline tw-mt-4"
className="tw:mx-auto tw:daisy-btn-outline tw:mt-4"
>
<BackIcon />
Back to safety

View file

@ -208,21 +208,21 @@ export const Set = ({ id, publicOnly = false, Link = false, measurementHelpProvi
const heading = (
<>
<div className="tw-flex tw-flex-wrap md:tw-flex-nowrap tw-flex-row tw-gap-2 tw-w-full">
<div className="tw-w-full md:tw-w-96 tw-shrink-0">
<div className="tw:flex tw:flex-wrap tw:md:flex-nowrap tw:flex-row tw:gap-2 tw:w-full">
<div className="tw:w-full tw:md:w-96 tw:shrink-0">
<MsetCard set={mset} control={control} Link={Link} />
</div>
<div className="tw-flex tw-flex-col tw-justify-end tw-gap-2 tw-mb-2 tw-grow">
<div className="tw:flex tw:flex-col tw:justify-end tw:gap-2 tw:mb-2 tw:grow">
{account.control > 2 && mset.public && mset.userId !== account.id ? (
<div className="tw-flex tw-flex-row tw-gap-2 tw-items-center">
<div className="tw:flex tw:flex-row tw:gap-2 tw:items-center">
<a
className="tw-daisy-badge tw-daisy-badge-secondary tw-font-bold tw-daisy-badge-lg"
className="tw:daisy-badge tw:daisy-badge-secondary tw:font-bold tw:daisy-badge-lg"
href={`${urls.backend}/sets/${mset.id}.json`}
>
JSON
</a>
<a
className="tw-daisy-badge tw-daisy-badge-success tw-font-bold tw-daisy-badge-lg"
className="tw:daisy-badge tw:daisy-badge-success tw:font-bold tw:daisy-badge-lg"
href={`${urls.backend}/sets/${mset.id}.yaml`}
>
YAML
@ -232,9 +232,9 @@ export const Set = ({ id, publicOnly = false, Link = false, measurementHelpProvi
<span></span>
)}
{account.control > 3 && mset.userId === account.id ? (
<div className="tw-flex tw-flex-row tw-gap-2 tw-items-center">
<div className="tw:flex tw:flex-row tw:gap-2 tw:items-center">
<button
className="tw-daisy-badge tw-daisy-badge-secondary tw-font-bold tw-daisy-badge-lg"
className="tw:daisy-badge tw:daisy-badge-secondary tw:font-bold tw:daisy-badge-lg"
onClick={() =>
setModal(
<ModalWrapper keepOpenOnClick>
@ -246,7 +246,7 @@ export const Set = ({ id, publicOnly = false, Link = false, measurementHelpProvi
JSON
</button>
<button
className="tw-daisy-badge tw-daisy-badge-success tw-font-bold tw-daisy-badge-lg tw-text-neutral-content"
className="tw:daisy-badge tw:daisy-badge-success tw:font-bold tw:daisy-badge-lg tw:text-neutral-content"
onClick={() =>
setModal(
<ModalWrapper keepOpenOnClick>
@ -263,11 +263,11 @@ export const Set = ({ id, publicOnly = false, Link = false, measurementHelpProvi
)}
{account.id && account.control > 2 && mset.public && mset.userId !== account.id ? (
<button
className="tw-daisy-btn tw-daisy-btn-primary"
className="tw:daisy-btn tw:daisy-btn-primary"
title="Import measurements set"
onClick={importSet}
>
<div className="tw-flex tw-flex-row tw-gap-4 tw-justify-between tw-items-center tw-w-full">
<div className="tw:flex tw:flex-row tw:gap-4 tw:justify-between tw:items-center tw:w-full">
<UploadIcon />
Import measurements set
</div>
@ -284,7 +284,7 @@ export const Set = ({ id, publicOnly = false, Link = false, measurementHelpProvi
</ModalWrapper>
)
}
className={`tw-daisy-btn tw-daisy-btn-secondary tw-btn-outline ${horFlexClasses}`}
className={`tw:daisy-btn tw:daisy-btn-secondary tw:btn-outline ${horFlexClasses}`}
>
<ShowcaseIcon />
Show Image
@ -297,9 +297,9 @@ export const Set = ({ id, publicOnly = false, Link = false, measurementHelpProvi
setSuggest(!suggest)
setEdit(false)
}}
className={`tw-daisy-btn ${
suggest ? 'tw-daisy-btn-neutral' : 'tw-daisy-btn-primary'
} tw-daisy-btn-outline ${horFlexClasses}`}
className={`tw:daisy-btn ${
suggest ? 'tw:daisy-btn-neutral' : 'tw:daisy-btn-primary'
} tw:daisy-btn-outline ${horFlexClasses}`}
>
{suggest ? <ResetIcon /> : <CuratedMeasurementsSetIcon />}
{suggest ? 'Cancel' : 'Suggest for curation'}
@ -312,14 +312,14 @@ export const Set = ({ id, publicOnly = false, Link = false, measurementHelpProvi
setEdit(false)
setSuggest(false)
}}
className={`tw-daisy-btn tw-daisy-btn-neutral tw-daisy-btn-outline ${horFlexClasses}`}
className={`tw:daisy-btn tw:daisy-btn-neutral tw:daisy-btn-outline ${horFlexClasses}`}
>
<ResetIcon />
Cancel
</button>
<button
onClick={save}
className={`tw-daisy-btn tw-daisy-btn-primary ${horFlexClasses}`}
className={`tw:daisy-btn tw:daisy-btn-primary ${horFlexClasses}`}
>
<UploadIcon />
Save measurements set
@ -331,7 +331,7 @@ export const Set = ({ id, publicOnly = false, Link = false, measurementHelpProvi
setEdit(true)
setSuggest(false)
}}
className={`tw-daisy-btn tw-daisy-btn-primary ${horFlexClasses}`}
className={`tw:daisy-btn tw:daisy-btn-primary ${horFlexClasses}`}
>
<EditIcon /> Edit measurements set
</button>
@ -340,14 +340,14 @@ export const Set = ({ id, publicOnly = false, Link = false, measurementHelpProvi
)}
{account.control > 1 && account?.compare ? (
<button
className="tw-daisy-btn tw-daisy-btn-secondary tw-btn-outline"
className="tw:daisy-btn tw:daisy-btn-secondary tw:btn-outline"
title="Validate measurements"
onClick={() => {
setRender(!render)
setEdit(false)
}}
>
<div className="tw-flex tw-flex-row tw-gap-4 tw-justify-between tw-items-center tw-w-full">
<div className="tw:flex tw:flex-row tw:gap-4 tw:justify-between tw:items-center tw:w-full">
<CompareIcon />
Validate measurements
</div>
@ -355,11 +355,11 @@ export const Set = ({ id, publicOnly = false, Link = false, measurementHelpProvi
) : null}
{account.control > 2 && mset.userId === account.id ? (
<button
className="tw-daisy-btn tw-daisy-btn-neutral"
className="tw:daisy-btn tw:daisy-btn-neutral"
title="Clone measurements set"
onClick={importSet}
>
<div className="tw-flex tw-flex-row tw-gap-4 tw-justify-between tw-items-center tw-w-full">
<div className="tw:flex tw:flex-row tw:gap-4 tw:justify-between tw:items-center tw:w-full">
<CloneIcon />
Clone measurements set
</div>
@ -367,13 +367,13 @@ export const Set = ({ id, publicOnly = false, Link = false, measurementHelpProvi
) : null}
</div>
</div>
<div className="tw-flex tw-flex-row tw-flex-wrap tw-gap-4 tw-text-sm tw-items-center tw-justify-between tw-mb-2"></div>
<div className="tw:flex tw:flex-row tw:flex-wrap tw:gap-4 tw:text-sm tw:items-center tw:justify-between tw:mb-2"></div>
</>
)
if (suggest)
return (
<div className="tw-w-full">
<div className="tw:w-full">
{heading}
<SuggestCset {...{ mset, setLoadingStatus, backend, Link }} />
</div>
@ -382,14 +382,14 @@ export const Set = ({ id, publicOnly = false, Link = false, measurementHelpProvi
if (!edit) {
if (render)
return (
<div className="tw-w-full">
<div className="tw:w-full">
{heading}
<RenderedCSet {...{ mset, setLoadingStatus, backend, imperial }} />
</div>
)
return (
<div className="tw-w-full">
<div className="tw:w-full">
{heading}
<h2>Data</h2>
@ -404,14 +404,14 @@ export const Set = ({ id, publicOnly = false, Link = false, measurementHelpProvi
<>
{mset.userId === account.id && (
<DisplayRow title="Public">
<div className="tw-flex tw-flex-row tw-gap-2 tw-items-center tw-justify-between">
<div className="tw:flex tw:flex-row tw:gap-2 tw:items-center tw:justify-between">
{mset.public ? (
<OkIcon className="tw-w-6 tw-h-6 tw-text-success" stroke={4} />
<OkIcon className="tw:w-6 tw:h-6 tw:text-success" stroke={4} />
) : (
<NoIcon className="tw-w-6 tw-h-6 tw-text-error" stroke={3} />
<NoIcon className="tw:w-6 tw:h-6 tw:text-error" stroke={3} />
)}
<button
className="tw-daisy-btn tw-daisy-btn-secondary tw-daisy-btn-sm"
className="tw:daisy-btn tw:daisy-btn-secondary tw:daisy-btn-sm"
onClick={togglePublic}
>
Make {mset.public ? 'Private' : 'Public'}
@ -432,13 +432,13 @@ export const Set = ({ id, publicOnly = false, Link = false, measurementHelpProvi
{control >= controlConfig.account.sets.createdAt && (
<DisplayRow title="Created">
{timeAgo(mset.createdAt, false)}
<span className="tw-text-sm tw-pl-2">({shortDate(mset.createdAt, false)})</span>
<span className="tw:text-sm tw:pl-2">({shortDate(mset.createdAt, false)})</span>
</DisplayRow>
)}
{control >= controlConfig.account.sets.updatedAt && (
<DisplayRow title="Updated">
{timeAgo(mset.updatedAt, false)}
<span className="tw-text-sm tw-pl-2">({shortDate(mset.updatedAt, false)})</span>
<span className="tw:text-sm tw:pl-2">({shortDate(mset.updatedAt, false)})</span>
</DisplayRow>
)}
{control >= controlConfig.account.sets.id && <DisplayRow title="ID">{mset.id}</DisplayRow>}
@ -458,7 +458,7 @@ export const Set = ({ id, publicOnly = false, Link = false, measurementHelpProvi
title={<MeasurementValue {...{ m, val, imperial: !displayAsMetric }} />}
key={m}
>
<span className="tw-font-medium">{measurementTranslations[m]}</span>
<span className="tw:font-medium">{measurementTranslations[m]}</span>
</DisplayRow>
) : null
)}
@ -469,10 +469,10 @@ export const Set = ({ id, publicOnly = false, Link = false, measurementHelpProvi
}
return (
<div className="tw-w-full">
<div className="tw:w-full">
{heading}
<h2 id="measies">Measurements</h2>
<div className="tw-bg-secondary tw-px-4 tw-pt-1 tw-pb-4 tw-rounded-lg tw-shadow tw-bg-opacity-10">
<div className="tw:bg-secondary/10 tw:px-4 tw:pt-1 tw:pb-4 tw:rounded-lg tw:shadow">
<DesignInput
update={setFilter}
label="Filter by design"
@ -531,10 +531,10 @@ export const Set = ({ id, publicOnly = false, Link = false, measurementHelpProvi
{
val: true,
label: (
<div className="tw-flex tw-flex-row tw-items-center tw-flex-wrap tw-justify-between tw-w-full">
<div className="tw:flex tw:flex-row tw:items-center tw:flex-wrap tw:justify-between tw:w-full">
<span>Public measurements set</span>
<OkIcon
className="tw-w-8 tw-h-8 tw-text-success tw-bg-base-100 tw-rounded-full tw-p-1"
className="tw:w-8 tw:h-8 tw:text-success tw:bg-base-100 tw:rounded-full tw:p-1"
stroke={4}
/>
</div>
@ -544,10 +544,10 @@ export const Set = ({ id, publicOnly = false, Link = false, measurementHelpProvi
{
val: false,
label: (
<div className="tw-flex tw-flex-row tw-items-center tw-flex-wrap tw-justify-between tw-w-full">
<div className="tw:flex tw:flex-row tw:items-center tw:flex-wrap tw:justify-between tw:w-full">
<span>Private measurements set</span>
<NoIcon
className="tw-w-8 tw-h-8 tw-text-error tw-bg-base-100 tw-rounded-full tw-p-1"
className="tw:w-8 tw:h-8 tw:text-error tw:bg-base-100 tw:rounded-full tw:p-1"
stroke={3}
/>
</div>
@ -571,9 +571,9 @@ export const Set = ({ id, publicOnly = false, Link = false, measurementHelpProvi
{
val: false,
label: (
<div className="tw-flex tw-flex-row tw-items-center tw-flex-wrap tw-justify-between tw-w-full">
<div className="tw:flex tw:flex-row tw:items-center tw:flex-wrap tw:justify-between tw:w-full">
<span>Metric units (cm)</span>
<span className="tw-text-inherit tw-text-2xl tw-pr-2">cm</span>
<span className="tw:text-inherit tw:text-2xl tw:pr-2">cm</span>
</div>
),
desc: 'Pick this if you prefer cm over inches',
@ -581,9 +581,9 @@ export const Set = ({ id, publicOnly = false, Link = false, measurementHelpProvi
{
val: true,
label: (
<div className="tw-flex tw-flex-row tw-items-center tw-flex-wrap tw-justify-between tw-w-full">
<div className="tw:flex tw:flex-row tw:items-center tw:flex-wrap tw:justify-between tw:w-full">
<span>Imperial units (inch)</span>
<span className="tw-text-inherit tw-text-4xl tw-pr-2"></span>
<span className="tw:text-inherit tw:text-4xl tw:pr-2"></span>
</div>
),
desc: 'Pick this if you prefer inches over cm',
@ -591,7 +591,7 @@ export const Set = ({ id, publicOnly = false, Link = false, measurementHelpProvi
]}
current={imperial}
/>
<span className="tw-text-large tw-text-warning">
<span className="tw:text-large tw:text-warning">
Note: You must save after changing Units to have the change take effect on this page.
</span>
</>
@ -610,7 +610,7 @@ export const Set = ({ id, publicOnly = false, Link = false, measurementHelpProvi
) : null}
<button
onClick={save}
className="tw-daisy-btn tw-daisy-btn-primary tw-daisy-btn-lg tw-flex tw-flex-row tw-items-center tw-gap-4 tw-mx-auto tw-mt-8"
className="tw:daisy-btn tw:daisy-btn-primary tw:daisy-btn-lg tw:flex tw:flex-row tw:items-center tw:gap-4 tw:mx-auto tw:mt-8"
>
<UploadIcon />
Save Measurements Set
@ -685,7 +685,7 @@ export const SuggestCset = ({ mset, Link }) => {
return (
<>
<h2>Suggest a measurements set for curation</h2>
<h4 className="tw-flex tw-flex-row tw-items-center tw-gap-2">
<h4 className="tw:flex tw:flex-row tw:items-center tw:gap-2">
{missing.length > 0 ? <BoolNoIcon /> : <BoolYesIcon />}
Measurements
</h4>
@ -696,7 +696,7 @@ export const SuggestCset = ({ mset, Link }) => {
of measurements.
</p>
<p>Your measurements set is missing the following measurements:</p>
<ul className="tw-list tw-list-inside tw-list-disc tw-ml-4">
<ul className="tw:list tw:list-inside tw:list-disc tw:ml-4">
{missing.map((m) => (
<li key={m}>{m}</li>
))}
@ -705,13 +705,13 @@ export const SuggestCset = ({ mset, Link }) => {
) : (
<p>All measurements are available.</p>
)}
<h4 className="tw-flex tw-flex-row tw-items-center tw-gap-2">
<h4 className="tw:flex tw:flex-row tw:items-center tw:gap-2">
{name.length > 1 ? <BoolYesIcon /> : <BoolNoIcon />}
Name
</h4>
<p>Each curated set has a name. You can suggest your own name or a pseudonym.</p>
<StringInput label="Name" current={name} update={setName} valid={(val) => val.length > 1} />
<h4 className="tw-flex tw-flex-row tw-items-center tw-gap-2">
<h4 className="tw:flex tw:flex-row tw:items-center tw:gap-2">
{height.length > 1 ? <BoolYesIcon /> : <BoolNoIcon />}
Height
</h4>
@ -725,7 +725,7 @@ export const SuggestCset = ({ mset, Link }) => {
update={setHeight}
valid={(val) => val.length > 1}
/>
<h4 className="tw-flex tw-flex-row tw-items-center tw-gap-2 tw-mt-4">
<h4 className="tw:flex tw:flex-row tw:items-center tw:gap-2 tw:mt-4">
{img.length > 0 ? <BoolYesIcon /> : <BoolNoIcon />}
Image
</h4>
@ -740,7 +740,7 @@ export const SuggestCset = ({ mset, Link }) => {
update={setImg}
valid={(val) => val.length > 1}
/>
<h4 className="tw-flex tw-flex-row tw-items-center tw-gap-2 tw-mt-4">
<h4 className="tw:flex tw:flex-row tw:items-center tw:gap-2 tw:mt-4">
<BoolYesIcon />
Notes
</h4>
@ -750,7 +750,7 @@ export const SuggestCset = ({ mset, Link }) => {
</Popout>
<MarkdownInput label="Notes" current={notes} update={setNotes} valid={() => true} />
<button
className="tw-daisy-btn tw-daisy-btn-primary tw-w-full tw-mt-4"
className="tw:daisy-btn tw:daisy-btn-primary tw:w-full tw:mt-4"
disabled={!(missing.length === 0 && height.length > 1 && img.length > 0)}
onClick={suggestSet}
>
@ -776,10 +776,10 @@ export const RenderedCSet = ({ mset, imperial }) => {
if (missing.length > 0)
return (
<>
<h4 className="tw-flex tw-flex-row tw-items-center tw-gap-2">Validation messages</h4>
<h4 className="tw:flex tw:flex-row tw:items-center tw:gap-2">Validation messages</h4>
<p>To validate and preview a measurement set, all measurements need to be entered.</p>
<p>Your measurements set is missing the following measurements:</p>
<ul className="tw-list tw-list-inside tw-list-disc tw-ml-4">
<ul className="tw:list tw:list-inside tw:list-disc tw:ml-4">
{missing.map((m) => (
<li key={m}>{m}</li>
))}
@ -793,7 +793,7 @@ export const RenderedCSet = ({ mset, imperial }) => {
console.log('flags', pattern, flags, strings)
return (
<>
<h4 className="tw-flex tw-flex-row tw-items-center tw-gap-2">Measurement analysis</h4>
<h4 className="tw:flex tw:flex-row tw:items-center tw:gap-2">Measurement analysis</h4>
<p>
Based on your measurements, we estimate your body to be about{' '}
<strong>{formatMm(pattern.parts[0].front.points.head.y * -1, imperial)}</strong> high.
@ -803,7 +803,7 @@ export const RenderedCSet = ({ mset, imperial }) => {
const desc = strings[flag.desc] || flag.desc
return (
<div key={key} className="tw-flex tw-flex-row tw-mt-4">
<div key={key} className="tw:flex tw:flex-row tw:mt-4">
{flag.type === 'warn' ? (
<MiniNote>
<Markdown>{desc}</Markdown>
@ -817,7 +817,7 @@ export const RenderedCSet = ({ mset, imperial }) => {
)
})}
<h4 className="tw-flex tw-flex-row tw-items-center tw-gap-2 tw-mt-12">Preview</h4>
<h4 className="tw:flex tw:flex-row tw:items-center tw:gap-2 tw:mt-12">Preview</h4>
{previewVisible ? (
<Pattern
renderProps={pattern.getRenderProps()}
@ -856,7 +856,7 @@ export const RenderedCSet = ({ mset, imperial }) => {
</li>
</ul>
<button
className={`tw-daisy-btn tw-daisy-btn-primary tw-mt-4`}
className={`tw:daisy-btn tw:daisy-btn-primary tw:mt-4`}
onClick={() => setPreviewVisible(true)}
>
<CompareIcon />I understand, render body preview
@ -896,7 +896,7 @@ export const NewSet = () => {
}
return (
<div className="tw-max-w-xl">
<div className="tw:max-w-xl">
<h5>Name</h5>
<p>Give this set of measurements a name. That will help tell them apart.</p>
<StringInput
@ -907,9 +907,9 @@ export const NewSet = () => {
valid={(val) => val && val.length > 0}
placeholder={'Georg Cantor'}
/>
<div className="tw-flex tw-flex-row tw-gap-2 tw-items-center tw-w-full tw-mt-8 tw-mb-2">
<div className="tw:flex tw:flex-row tw:gap-2 tw:items-center tw:w-full tw:mt-8 tw:mb-2">
<button
className="tw-daisy-btn tw-daisy-btn-primary tw-grow tw-capitalize"
className="tw:daisy-btn tw:daisy-btn-primary tw:grow tw:capitalize"
disabled={name.length < 1}
onClick={createSet}
>

View file

@ -85,19 +85,19 @@ export const Sets = ({ Link = false }) => {
}
return (
<div className="tw-max-w-7xl xl:tw-pl-4">
<p className="tw-text-center md:tw-text-right">
<div className="tw:max-w-7xl tw:xl:pl-4">
<p className="tw:text-center tw:md:text-right">
<Link
className="tw-daisy-btn tw-daisy-btn-primary tw-daisy-btn-outline tw-capitalize tw-w-full md:tw-w-auto tw-mr-2 tw-mb-2 hover:tw-no-underline hover:tw-text-primary-content"
className="tw:daisy-btn tw:daisy-btn-secondary tw:capitalize tw:w-full tw:md:w-auto tw:mr-2 tw:hover:no-underline tw:hover:text-primary-content no-hover-decoration"
bottom
primary
href="/account/import"
>
<UploadIcon />
Import Measurements Sets
<UploadIcon className="tw:w-6 tw:h-6 tw:text-secondary-content" />
<span className="tw:text-secondary-content">Import Measurements Sets</span>
</Link>
<button
className="tw-daisy-btn tw-daisy-btn-primary tw-capitalize tw-w-full md:tw-w-auto hover:tw-no-underline hover:tw-text-primary-content"
className="tw:daisy-btn tw:daisy-btn-primary tw:capitalize tw:w-full tw:md:w-auto tw:hover:no-underline tw:hover:text-primary-content"
onClick={() =>
setModal(
<ModalWrapper keepOpenOnClick>
@ -110,41 +110,41 @@ export const Sets = ({ Link = false }) => {
Create a new Measurements Set
</button>
</p>
<div className="tw-flex tw-flex-row tw-gap-2 tw-border-b-2 tw-mb-4 tw-pb-4 tw-mt-8 tw-h-14 tw-items-center">
<div className="tw:flex tw:flex-row tw:gap-2 tw:border-b-2 tw:mb-4 tw:pb-4 tw:mt-8 tw:h-14 tw:items-center">
<input
type="checkbox"
className="tw-daisy-checkbox tw-daisy-checkbox-secondary"
className="tw:daisy-checkbox tw:daisy-checkbox-secondary"
onClick={toggleSelectAll}
checked={sets.length === selCount}
/>
<button
className="tw-daisy-btn tw-daisy-btn-error"
className="tw:daisy-btn tw:daisy-btn-error"
onClick={removeSelectedSets}
disabled={selCount < 1}
>
<TrashIcon /> {selCount} Measurements Sets
</button>
</div>
<div className="tw-grid tw-grid-cols-2 lg:tw-grid-cols-4 tw-gap-2">
<div className="tw:grid tw:grid-cols-2 tw:lg:grid-cols-4 tw:gap-2">
{sets.map((set, i) => (
<div
key={i}
className={`tw-flex tw-flex-row tw-items-start tw-gap-1 tw-border-2
className={`tw:flex tw:flex-row tw:items-start tw:gap-1 tw:border-2
${
selected[set.id]
? 'tw-border-solid tw-border-secondary'
: 'tw-border-dotted tw-border-base-300'
} tw-rounded-lg p-2`}
? 'tw:border-solid tw:border-secondary'
: 'tw:border-dotted tw:border-base-300'
} tw:rounded-lg p-2`}
>
<label className="tw-w-8 tw-h-full tw-shrink-0">
<label className="tw:w-8 tw:h-full tw:shrink-0">
<input
type="checkbox"
checked={selected[set.id] ? true : false}
className="tw-daisy-checkbox tw-daisy-checkbox-secondary"
className="tw:daisy-checkbox tw:daisy-checkbox-secondary"
onClick={() => toggleSelect(set.id)}
/>
</label>
<div className="tw-w-full">
<div className="tw:w-full">
<MsetCard
control={control}
href={`/account/data/sets/set?id=${set.id}`}
@ -189,9 +189,9 @@ export const MsetCard = ({
const s = sizes[size]
const wrapperProps = {
className: `tw-bg-base-300 tw-aspect-square tw-h-${s} tw-w-${s} tw-mb-2 tw-grow tw-w-full
hover:tw-cursor-pointer tw-border-0 tw-opacity-80 hover:tw-opacity-100
tw-mx-auto tw-flex tw-flex-col tw-items-start tw-text-center tw-justify-between tw-rounded-none md:tw-rounded shadow`,
className: `tw:bg-base-300 tw:aspect-square tw:h-${s} tw:w-${s} tw:mb-2 tw:grow tw:w-full
tw:hover:cursor-pointer tw:border-0 tw:opacity-80 tw:hover:opacity-100
tw:mx-auto tw:flex tw:flex-col tw:items-start tw:text-center tw:justify-between tw:rounded-none tw:md:rounded shadow`,
style: {
backgroundImage: `url(${cloudflareImageUrl({ type: 'w500', id: set.img })})`,
backgroundSize: 'cover',
@ -212,11 +212,11 @@ export const MsetCard = ({
set.measies,
true
)
const iconClasses = 'tw-w-8 tw-h-8 tw-p-1 tw-rounded-full tw--mt-2 tw--ml-2 tw-shadow'
const iconClasses = 'tw:w-8 tw:h-8 tw:p-1 tw:rounded-full tw:-mt-2 tw:-ml-2 tw:shadow'
icon = hasMeasies ? (
<OkIcon className={`${iconClasses} tw-bg-success tw-text-success-content`} stroke={4} />
<OkIcon className={`${iconClasses} tw:bg-success tw:text-success-content`} stroke={4} />
) : (
<NoIcon className={`${iconClasses} tw-bg-error tw-text-error-content`} stroke={3} />
<NoIcon className={`${iconClasses} tw:bg-error tw:text-error-content`} stroke={3} />
)
if (missing.length > 0) {
const translated = missing.map((m) => measurementsTranslations[m])
@ -225,7 +225,7 @@ export const MsetCard = ({
const lastSpace = missingString.lastIndexOf(', ', maxLength)
missingString = missingString.substring(0, lastSpace) + ', and more...'
}
const measieClasses = 'tw-font-normal tw-text-xs'
const measieClasses = 'tw:font-normal tw:text-xs'
missingMeasies = <span className={`${measieClasses}`}>{missingString}</span>
linebreak = <br />
}
@ -234,7 +234,7 @@ export const MsetCard = ({
const inner = (
<>
{icon}
<span className="tw-bg-neutral tw-text-neutral-content tw-px-4 tw-w-full tw-bg-opacity-50 tw-py-2 tw-rounded tw-rounded-t-none tw-font-bold tw-leading-5">
<span className="tw:bg-neutral/50 tw:text-neutral-content tw:px-4 tw:w-full tw:py-2 tw:rounded tw:rounded-t-none tw:font-bold tw:leading-5">
{set.name}
{linebreak}
{missingMeasies}

View file

@ -54,14 +54,14 @@ export const Units = ({ welcome = false }) => {
: '/docs/about/guide'
return (
<div className="tw-w-full">
<div className="tw:w-full">
<ListInput
id="account-units"
label="Units"
list={['metric', 'imperial'].map((val) => ({
val,
label: (
<div className="tw-flex tw-flex-row tw-items-center tw-w-full tw-justify-between">
<div className="tw:flex tw:flex-row tw:items-center tw:w-full tw:justify-between">
<span>{val === 'metric' ? 'Metric units (cm)' : 'Imperial units (inch)'}</span>
<NumberCircle nr={val === 'imperial' ? '″' : 'cm'} color="secondary" />
</div>
@ -76,17 +76,17 @@ export const Units = ({ welcome = false }) => {
/>
{welcome ? (
<>
<IconButton href={nextHref} className="tw-mt-4">
<IconButton href={nextHref} className="tw:mt-4">
<RightIcon stroke={3} /> Continue
</IconButton>
{welcomeSteps[account?.control].length > 0 ? (
<>
<progress
className="tw-daisy-progress tw-daisy-progress-primary tw-w-full tw-mt-12"
className="tw:daisy-progress tw:daisy-progress-primary tw:w-full tw:mt-12"
value={300 / welcomeSteps[account?.control].length}
max="100"
></progress>
<span className="tw-pt-4 tw-text-sm tw-font-bold tw-opacity-50">
<span className="tw:pt-4 tw:text-sm tw:font-bold tw:opacity-50">
3 / {welcomeSteps[account?.control].length}
</span>
<WelcomeIcons

View file

@ -60,7 +60,7 @@ export const Username = ({ welcome = false, Link = false }) => {
else btnClasses += 'w-full daisy-btn-primary'
return (
<div className="tw-w-full">
<div className="tw:w-full">
<StringInput
id="account-username"
label="Username"
@ -69,24 +69,24 @@ export const Username = ({ welcome = false, Link = false }) => {
valid={() => available}
placeholder={'Sorcha Ni Dhubghaill'}
labelBL={
<span className="tw-flex tw-flex-row tw-gap-1 tw-items-center">
<span className="tw:flex tw:flex-row tw:gap-1 tw:items-center">
{available ? (
<>
<OkIcon className="tw-w-4 tw-h-4 tw-text-success" stroke={4} /> Username is
<OkIcon className="tw:w-4 tw:h-4 tw:text-success" stroke={4} /> Username is
available
</>
) : (
<>
<NoIcon className="tw-w-4 tw-h-4 tw-text-error" stroke={3} /> This username is taken
<NoIcon className="tw:w-4 tw:h-4 tw:text-error" stroke={3} /> This username is taken
</>
)}
</span>
}
/>
<p className="tw-text-right">
<p className="tw:text-right">
<button
disabled={!available}
className="tw-daisy-btn tw-daisy-btn-primary tw-w-full lg:tw-w-auto tw-mt-8"
className="tw:daisy-btn tw:daisy-btn-primary tw:w-full tw:lg:w-auto tw:mt-8"
onClick={save}
>
<SaveIcon /> Save Username
@ -95,17 +95,17 @@ export const Username = ({ welcome = false, Link = false }) => {
{welcome ? (
<>
<IconButton href={nextHref} className="tw-mt-4">
<IconButton href={nextHref} className="tw:mt-4">
<RightIcon stroke={3} /> Continue
</IconButton>
{welcomeSteps[account.control].length > 0 ? (
<>
<progress
className="tw-daisy-progress tw-daisy-progress-primary tw-w-full tw-mt-12"
className="tw:daisy-progress tw:daisy-progress-primary tw:w-full tw:mt-12"
value={500 / welcomeSteps[account.control].length}
max="100"
></progress>
<span className="tw-pt-4 tw-text-sm tw-font-bold tw-opacity-50">
<span className="tw:pt-4 tw:text-sm tw:font-bold tw:opacity-50">
5 / {welcomeSteps[account.control].length}
</span>
<WelcomeIcons

View file

@ -17,14 +17,14 @@ import {
/*
* A component to display a row of data
*/
export const DisplayRow = ({ title, children, keyWidth = 'tw-w-24' }) => (
<div className="tw-flex tw-flex-row tw-flex-wrap tw-items-center lg:tw-gap-4 tw-my-2 tw-w-full">
export const DisplayRow = ({ title, children, keyWidth = 'tw:w-24' }) => (
<div className="tw:flex tw:flex-row tw:flex-wrap tw:items-center tw:lg:gap-4 tw:my-2 tw:w-full">
<div
className={`${keyWidth} tw-text-left md:tw-text-right tw-block md:tw-inline tw-font-bold tw-pr-4 tw-shrink-0`}
className={`${keyWidth} tw:text-left tw:md:text-right tw:block tw:md:inline tw:font-bold tw:pr-4 tw:shrink-0`}
>
{title}
</div>
<div className="tw-grow">{children}</div>
<div className="tw:grow">{children}</div>
</div>
)
@ -37,14 +37,14 @@ export const welcomeSteps = {
}
export const WelcomeDoneIcon = ({ href }) => (
<Link href={`/welcome/${href}`} className="tw-text-success hover:tw-text-secondary">
<Link href={`/welcome/${href}`} className="tw:text-success tw:hover:text-secondary">
<WelcomeTopicIcon href={href} />
</Link>
)
export const WelcomeTodoIcon = ({ href }) => (
<Link
href={`/welcome/${href}`}
className="tw-text-secondary tw-w-6 tw-h-6 tw-opacity-50 hover:tw-opacity-100"
className="tw:text-secondary tw:w-6 tw:h-6 tw:opacity-50 tw:hover:opacity-100"
>
<WelcomeTopicIcon href={href} />
</Link>
@ -62,11 +62,11 @@ const WelcomeTopicIcon = (props) => {
}
const WelcomeDoingIcon = ({ href }) => (
<WelcomeTopicIcon href={href} className="tw-w-6 tw-h-6 tw-text-base-content" />
<WelcomeTopicIcon href={href} className="tw:w-6 tw:h-6 tw:text-base-content" />
)
export const WelcomeIcons = ({ done = [], todo = [], current = '' }) => (
<div className="tw-m-auto tw-flex tw-flex-row tw-items-center tw-justify-center tw-gap-2">
<div className="tw:m-auto tw:flex tw:flex-row tw:items-center tw:justify-center tw:gap-2">
{done.map((href) => (
<WelcomeDoneIcon href={href} key={href} />
))}

View file

@ -53,37 +53,37 @@ export const SubscriberAdministration = ({ page }) => {
{subscribers ? (
<>
<h5>Search subscribers</h5>
<div className="tw-flex tw-flex-row tw-gap-2 tw-items-center">
<div className="tw:flex tw:flex-row tw:gap-2 tw:items-center">
<input
autoFocus
value={q}
onChange={(evt) => setQ(evt.target.value)}
className="tw-daisy-input tw-w-full tw-daisy-input-bordered tw-flex tw-flex-row"
className="tw:daisy-input tw:w-full tw:daisy-input-bordered tw:flex tw:flex-row"
type="text"
placeholder="Username, ID, or E-mail address"
/>
<button onClick={search} className="tw-daisy-btn tw-daisy-btn-primary">
<button onClick={search} className="tw:daisy-btn tw:daisy-btn-primary">
<SearchIcon />
</button>
</div>
<table className="tw-table tw-my-4">
<table className="tw:table tw:my-4">
<thead>
<tr>
<th className="tw-text-right">Email</th>
<th className="tw-w-12">Language</th>
<th className="tw:text-right">Email</th>
<th className="tw:w-12">Language</th>
<th>Unsubscribe</th>
</tr>
</thead>
<tbody>
{hits.map((hit, i) => (
<tr key={i}>
<td className="tw-text-right">
<td className="tw:text-right">
<b>{hit.email}</b>
</td>
<td className="tw-w-12">{hit.lang.toUpperCase()}</td>
<td className="tw-w-full">
<td className="tw:w-12">{hit.lang.toUpperCase()}</td>
<td className="tw:w-full">
<button
className="tw-daisy-btn tw-daisy-btn-link"
className="tw:daisy-btn tw:daisy-btn-link"
onClick={() => unsubscribe(hit.ehash)}
>
Unsubscribe
@ -96,7 +96,7 @@ export const SubscriberAdministration = ({ page }) => {
</>
) : (
<button
className="tw-daisy-btn tw-daisy-btn-primary tw-daisy-btn-lg"
className="tw:daisy-btn tw:daisy-btn-primary tw:daisy-btn-lg"
onClick={loadSubscribers}
>
Load Subscribers
@ -127,21 +127,21 @@ export const UserAdministration = ({ Link = false }) => {
return (
<>
<div className="tw-flex tw-flex-row tw-gap-8 tw-items-start tw-w-full">
<div className="tw-grow">
<div className="tw:flex tw:flex-row tw:gap-8 tw:items-start tw:w-full">
<div className="tw:grow">
<h5>Search users</h5>
<div className="tw-flex tw-flex-row tw-gap-2 tw-items-center">
<div className="tw:flex tw:flex-row tw:gap-2 tw:items-center">
<input
autoFocus
value={q}
onChange={(evt) => setQ(evt.target.value)}
className="tw-daisy-input tw-w-full tw-daisy-input-bordered tw-flex tw-flex-row"
className="tw:daisy-input tw:w-full tw:daisy-input-bordered tw:flex tw:flex-row"
type="text"
placeholder="Username, ID, or E-mail address"
/>
<button
onClick={search}
className="tw-daisy-btn tw-daisy-btn-primary"
className="tw:daisy-btn tw:daisy-btn-primary"
disabled={q.length < 3}
>
<SearchIcon />
@ -183,9 +183,9 @@ export const User = ({ user, Link }) => {
const { setModal } = useContext(ModalContext)
return (
<div className="tw-flex tw-flex-row tw-w-full tw-gap-4 tw-my-2">
<div className="tw:flex tw:flex-row tw:w-full tw:gap-4 tw:my-2">
<button
className="tw-w-24 tw-h-24 tw-bg-base-100 tw-rounded-lg tw-shadow tw-shrink-0"
className="tw:w-24 tw:h-24 tw:bg-base-100 tw:rounded-lg tw:shadow tw:shrink-0"
onClick={() =>
setModal(
<ModalWrapper>
@ -199,18 +199,18 @@ export const User = ({ user, Link }) => {
backgroundColor: '#ccc',
}}
></button>
<div className="tw-w-full tw-flex tw-flex-col tw-gap-1">
<div className="tw-w-full tw-flex tw-flex-row tw-flex-wrap tw-gap-1">
<div className="tw:w-full tw:flex tw:flex-col tw:gap-1">
<div className="tw:w-full tw:flex tw:flex-row tw:flex-wrap tw:gap-1">
<Link href={`/users/?id=${user.id}`}>{user.username}</Link>
<KeyVal k="id" val={user.id} />
</div>
<div className="tw-w-full tw-flex tw-flex-row tw-flex-wrap tw-gap-1">
<div className="tw:w-full tw:flex tw:flex-row tw:flex-wrap tw:gap-1">
<UserRole role={user.role} />
<AccountStatus status={user.status} />
</div>
<div className="tw-w-full tw-flex tw-flex-row tw-flex-wrap tw-gap-1">
<div className="tw:w-full tw:flex tw:flex-row tw:flex-wrap tw:gap-1">
<button
className="tw-daisy-btn tw-daisy-btn-primary tw-daisy-btn-sm tw-daisy-btn-outline"
className="tw:daisy-btn tw:daisy-btn-primary tw:daisy-btn-sm tw:daisy-btn-outline"
onClick={() =>
setModal(
<ModalWrapper>
@ -246,7 +246,7 @@ export const ImpersonateButton = ({ userId }) => {
return (
<button
className="tw-daisy-btn tw-daisy-btn-primary tw-daisy-btn-sm tw-daisy-btn-outline"
className="tw:daisy-btn tw:daisy-btn-primary tw:daisy-btn-sm tw:daisy-btn-outline"
onClick={impersonateUser}
>
Impersonate

View file

@ -12,21 +12,21 @@ export const Breadcrumbs = ({ crumbs = [], title, Link = false }) => {
if (Link === false) Link = RegularLink
return (
<div className="tw-tailwind-container tw-p-0">
<div className="tw:tailwind-container tw:p-0">
<ul
className="tw-flex tw-flex-row tw-items-center tw-gap-2 tw-m-0 tw-py-4"
className="tw:flex tw:flex-row tw:items-center tw:gap-2 tw:m-0 tw:py-4"
style={{ paddingLeft: 0 }}
>
<li className="tw-inline">
<li className="tw:inline">
<Link href="/">Home</Link>
</li>
<Spacer />
{crumbs.map((crumb, i) => (
<li key={i} className="tw-inline">
<li key={i} className="tw:inline">
<Link href={crumb.href}>{crumb.label}</Link>
</li>
))}
<li className="tw-inline">{title}</li>
<li className="tw:inline">{title}</li>
</ul>
</div>
)
@ -42,4 +42,4 @@ const RegularLink = ({ href, children }) => <a href={href}>{children}</a>
/*
* This goes between breadcrumbs
*/
const Spacer = () => <li className="tw-inline">&raquo;</li>
const Spacer = () => <li className="tw:inline">&raquo;</li>

View file

@ -19,7 +19,7 @@ export const IconButton = ({
btnProps = {},
}) => {
const allProps = {
className: `${staticLinkClasses} tw-daisy-btn-${color} hover:tw-text-${color}-content ${className}`,
className: `${staticLinkClasses} tw:daisy-btn-${color} hover:tw:text-${color}-content ${className}`,
title: title,
...btnProps,
}
@ -30,5 +30,5 @@ export const IconButton = ({
}
const staticLinkClasses =
'tw-flex tw-flex-row tw-gap-2 lg:tw-gap-6 tw-items-center tw-grow ' +
'tw-justify-between tw-w-full md:tw-w-auto tw-daisy-btn hover:tw-no-underline tw-capitalize'
'tw:flex tw:flex-row tw:gap-2 tw:lg:gap-6 tw:items-center tw:grow ' +
'tw:justify-between tw:w-full tw:md:w-auto tw:daisy-btn tw:hover:no-underline tw:capitalize'

View file

@ -102,8 +102,8 @@ export const Collection = ({ Link = false, linkTo = 'about', editor = false, onC
return (
<>
<div className="tw-max-w-7xl tw-m-auto">
<div className="tw-flex tw-flex-row tw-flex-wrap tw-gap-1 tw-justify-center tw-font-medium tw-mb-2">
<div className="tw:max-w-7xl tw:m-auto">
<div className="tw:flex tw:flex-row tw:flex-wrap tw:gap-1 tw:justify-center tw:font-medium tw:mb-2">
{Object.keys(filtered)
.sort()
.map((d) =>
@ -111,7 +111,7 @@ export const Collection = ({ Link = false, linkTo = 'about', editor = false, onC
<button
key={d}
onClick={() => onClick(d)}
className="tw-text-secondary tw-decoration-2 tw-underline tw-capitalize hover:tw-decoration-4 hover:tw-text-secondary tw-bg-transparent tw-border-0 tw-font-medium tw-p-0 tw-text-base hover:tw-cursor-pointer"
className="tw:text-secondary tw:decoration-2 tw:underline tw:capitalize tw:hover:decoration-4 tw:hover:text-secondary tw:bg-transparent tw:border-0 tw:font-medium tw:p-0 tw:text-base tw:hover:cursor-pointer"
>
{d}
</button>
@ -119,7 +119,7 @@ export const Collection = ({ Link = false, linkTo = 'about', editor = false, onC
<Link
key={d}
href={linkBuilders[linkTo](d)}
className="tw-text-secondary tw-decoration-2 tw-underline tw-capitalize hover:tw-decoration-4 hover:tw-text-secondary"
className="tw:text-secondary tw:decoration-2 tw:underline tw:capitalize tw:hover:decoration-4 tw:hover:text-secondary"
>
{d}
</Link>
@ -128,19 +128,19 @@ export const Collection = ({ Link = false, linkTo = 'about', editor = false, onC
</div>
{showFilters ? (
<>
<h6 className="tw-text-center tw-mb-0 tw-mt-4">
<h6 className="tw:text-center tw:mb-0 tw:mt-4">
Filters ({Object.keys(filtered).length}/{collection.length})
</h6>
<div className="tw-flex tw-flex-row tw-gap-1 tw-items-center tw-justify-center tw-flex-wrap tw-my-2">
<div className="tw:flex tw:flex-row tw:gap-1 tw:items-center tw:justify-center tw:flex-wrap tw:my-2">
<b>Tags:</b>
{tags.map((tag) => (
<button
key={tag}
className={`tw-daisy-badge tw-font-medium hover:tw-shadow hover:tw-cursor-pointer
className={`tw:daisy-badge tw:font-medium tw:hover:shadow tw:hover:cursor-pointer
${
filter?.tag && Array.isArray(filter.tag) && filter.tag.includes(tag)
? 'tw-daisy-badge-success hover:tw-daisy-badge-error'
: 'tw-daisy-badge-primary hover:tw-daisy-badge-success'
? 'tw:daisy-badge-success hover:tw:daisy-badge-error'
: 'tw:daisy-badge-primary hover:tw:daisy-badge-success'
}`}
onClick={() => toggle('tag', tag)}
>
@ -148,16 +148,16 @@ export const Collection = ({ Link = false, linkTo = 'about', editor = false, onC
</button>
))}
</div>
<div className="tw-flex tw-flex-row tw-gap-1 tw-items-center tw-justify-center tw-flex-wrap tw-my-4">
<div className="tw:flex tw:flex-row tw:gap-1 tw:items-center tw:justify-center tw:flex-wrap tw:my-4">
<b>Techniques</b>
{techniques.sort().map((tech) => (
<button
key={tech}
className={`tw-daisy-badge tw-font-medium hover:tw-shadow
className={`tw:daisy-badge tw:font-medium tw:hover:shadow
${
filter?.tech && Array.isArray(filter.tech) && filter.tech.includes(tech)
? 'tw-daisy-badge tw-daisy-badge-success hover:tw-daisy-badge-error'
: 'tw-daisy-badge tw-daisy-badge-accent hover:tw-daisy-badge-success'
? 'tw:daisy-badge tw:daisy-badge-success hover:tw:daisy-badge-error'
: 'tw:daisy-badge tw:daisy-badge-accent hover:tw:daisy-badge-success'
}`}
onClick={() => toggle('tech', tech)}
>
@ -165,39 +165,39 @@ export const Collection = ({ Link = false, linkTo = 'about', editor = false, onC
</button>
))}
</div>
<div className="tw-flex tw-flex-row tw-gap-2 tw-items-center tw-justify-center tw-flex-wrap tw-my-4">
<div className="tw:flex tw:flex-row tw:gap-2 tw:items-center tw:justify-center tw:flex-wrap tw:my-4">
<b>Difficulty:</b>
{[1, 2, 3, 4, 5].map((score) => (
<button
onClick={() => updateFilter('difficulty', score)}
key={score}
className={`tw-daisy-btn tw-daisy-btn-sm ${
className={`tw:daisy-btn tw:daisy-btn-sm ${
filter.difficulty === score
? 'tw-daisy-btn-secondary tw-daisy-btn-outline'
: 'tw-daisy-btn-ghost'
? 'tw:daisy-btn-secondary tw:daisy-btn-outline'
: 'tw:daisy-btn-ghost'
}`}
>
<Difficulty score={score} />
</button>
))}
</div>
<div className="tw-flex tw-flex-row tw-gap-4 tw-items-center tw-justify-center tw-flex-wrap tw-my-2">
<div className="tw:flex tw:flex-row tw:gap-4 tw:items-center tw:justify-center tw:flex-wrap tw:my-2">
<button
className="tw-daisy-btn tw-daisy-btn-secondary tw-daisy-btn-outline"
className="tw:daisy-btn tw:daisy-btn-secondary tw:daisy-btn-outline"
onClick={() => updateFilter('example', !filter.example)}
>
{filter.example ? <CisFemaleIcon /> : <ShowcaseIcon />}
{filter.example ? 'Show Line Drawings' : 'Show Examples'}
</button>
<button
className="tw-daisy-btn tw-daisy-btn-secondary tw-daisy-btn-outline"
className="tw:daisy-btn tw:daisy-btn-secondary tw:daisy-btn-outline"
onClick={() => setFilter({ example: 1 })}
>
<ResetIcon />
Clear Filter
</button>
<button
className="tw-daisy-btn tw-daisy-btn-secondary tw-daisy-btn-outline"
className="tw:daisy-btn tw:daisy-btn-secondary tw:daisy-btn-outline"
onClick={() => setShowFilters(false)}
>
<FilterIcon />
@ -206,16 +206,16 @@ export const Collection = ({ Link = false, linkTo = 'about', editor = false, onC
</div>
</>
) : (
<div className="tw-flex tw-flex-row tw-gap-4 tw-items-center tw-justify-center tw-flex-wrap tw-my-2">
<div className="tw:flex tw:flex-row tw:gap-4 tw:items-center tw:justify-center tw:flex-wrap tw:my-2">
<button
className="tw-daisy-btn tw-daisy-btn-secondary tw-daisy-btn-outline"
className="tw:daisy-btn tw:daisy-btn-secondary tw:daisy-btn-outline"
onClick={() => updateFilter('example', !filter.example)}
>
{filter.example ? <CisFemaleIcon /> : <ShowcaseIcon />}
{filter.example ? 'Show Line Drawings' : 'Show Examples'}
</button>
<button
className="tw-daisy-btn tw-daisy-btn-secondary tw-daisy-btn-outline"
className="tw:daisy-btn tw:daisy-btn-secondary tw:daisy-btn-outline"
onClick={() => setShowFilters(true)}
>
<FilterIcon />
@ -225,7 +225,7 @@ export const Collection = ({ Link = false, linkTo = 'about', editor = false, onC
)}
</div>
<div
className={`tw-grid tw-grid-cols-2 tw-gap-2 tw-mt-4 tw-justify-center sm:tw-grid-cols-3 md:tw-grid-cols-4 ${editor ? 'lg:tw-grid-cols-6 2xl:tw-grid-cols-12' : ''} tw-mb-8`}
className={`tw:grid tw:grid-cols-2 tw:gap-2 tw:mt-4 tw:justify-center tw:sm:grid-cols-3 tw:md:grid-cols-4 ${editor ? 'tw:lg:grid-cols-6 tw:2xl:grid-cols-12' : ''} tw:mb-8`}
>
{Object.keys(filtered)
.sort()
@ -253,7 +253,7 @@ export const Collection = ({ Link = false, linkTo = 'about', editor = false, onC
const Technique = ({ Link = WebLink, technique }) => (
<Link
href={`/designs/techniques/${technique}`}
className="tw-daisy-badge tw-daisy-badge-accent hover:tw-daisy-badge-secondary hover:tw-shadow tw-font-medium"
className="tw:daisy-badge tw:daisy-badge-accent hover:tw:daisy-badge-secondary tw:hover:shadow tw:font-medium"
>
{technique}
</Link>
@ -269,7 +269,7 @@ const Technique = ({ Link = WebLink, technique }) => (
const Tag = ({ Link = WebLink, technique }) => (
<Link
href={`/designs/tags/${tag}`}
className="tw-daisy-badge tw-daisy-badge-primary hover:tw-daisy-badge-secondary hover:tw-shadow tw-font-medium"
className="tw:daisy-badge tw:daisy-badge-primary hover:tw:daisy-badge-secondary tw:hover:shadow tw:font-medium"
>
{tag}
</Link>
@ -292,28 +292,28 @@ const DesignCard = ({ name, lineDrawing = false, linkTo, Link, onClick }) => {
const inner = (
<div
className={`tw-flex tw-flex-col tw-flex-nowrap tw-items-start tw-justify-between tw-gap-2 tw-border-neutral-500 group-hover:tw-border-secondary
tw-w-full tw-h-full tw-border tw-border-2 tw-border-solid tw-p-0 tw-relative tw-rounded-lg tw-rounded-lg`}
className={`tw:flex tw:flex-col tw:flex-nowrap tw:items-start tw:justify-between tw:gap-2 tw:border-neutral-500 tw:group-hover:border-secondary
tw:w-full tw:h-full tw:border tw:border-2 tw:border-solid tw:p-0 tw:relative tw:rounded-lg tw:rounded-lg`}
style={bg}
>
<h5
className={`tw-text-center tw-py-2 tw-px-4 tw-rounded-t tw-m-0 tw-w-full group-hover:tw-no-underline group-hover:tw-bg-secondary group-hover:tw-bg-opacity-70
${lineDrawing ? '' : 'tw-bg-neutral tw-text-neutral-content tw-bg-opacity-80'}`}
className={`tw:text-center tw:py-2 tw:px-4 tw:rounded-t tw:m-0 tw:w-full tw:group-hover:no-underline tw:group-hover:bg-secondary/70
${lineDrawing ? '' : 'tw:bg-neutral/80 tw:text-neutral-content'}`}
>
{about[name].name}
</h5>
{lineDrawing ? (
<div className="tw-p-1 tw-grow tw-w-full tw-h-auto tw-square tw-text-center">
<LineDrawing className="tw-max-w-full tw-m-auto tw-my-4 tw-text-base-content" />
<div className="tw:p-1 tw:grow tw:w-full tw:h-auto tw:square tw:text-center">
<LineDrawing className="tw:max-w-full tw:m-auto tw:my-4 tw:text-base-content" />
</div>
) : (
<span />
)}
<div
className={`tw-flex tw-flex-row tw-items-center tw-justify-center tw-py-1 tw-px-2 tw-rounded-b tw-m-0 tw-w-full
${lineDrawing ? '' : `tw-text-neutral-content`}`}
className={`tw:flex tw:flex-row tw:items-center tw:justify-center tw:py-1 tw:px-2 tw:rounded-b tw:m-0 tw:w-full
${lineDrawing ? '' : `tw:text-neutral-content`}`}
>
<Difficulty score={about[name].difficulty} className="group-hover:tw-text-secondary" />
<Difficulty score={about[name].difficulty} className="tw:group-hover:text-secondary" />
</div>
</div>
)
@ -321,7 +321,7 @@ const DesignCard = ({ name, lineDrawing = false, linkTo, Link, onClick }) => {
return onClick ? (
<button
onClick={() => onClick(name)}
className="hover:tw-bg-secondary hover:tw-bg-opacity-10 tw-rounded-lg tw-group hover:tw-no-underline tw-bg-transparent tw-border-0 hover:tw-cursor-pointer tw-p-0"
className="tw:hover:bg-secondary/10 tw:rounded-lg tw:group tw:hover:no-underline tw:bg-transparent tw:border-0 tw:hover:cursor-pointer tw:p-0"
title={about[name].description}
>
{inner}
@ -329,7 +329,7 @@ const DesignCard = ({ name, lineDrawing = false, linkTo, Link, onClick }) => {
) : (
<Link
href={linkBuilders[linkTo](name)}
className="hover:tw-bg-secondary hover:tw-bg-opacity-10 tw-rounded-lg tw-group hover:tw-no-underline"
className="tw:hover:bg-secondary/10 tw:rounded-lg tw:group tw:hover:no-underline"
title={about[name].description}
>
{inner}
@ -344,9 +344,9 @@ const DesignCard = ({ name, lineDrawing = false, linkTo, Link, onClick }) => {
* @param {number} props.score - The difficulty score of the design (1-5)
*/
const Difficulty = ({ score = 0, className = '' }) => (
<div className={`tw-flex tw-flex-row tw-items-center ${className}`}>
<div className={`tw:flex tw:flex-row tw:items-center ${className}`}>
{[0, 1, 2, 3, 4].map((i) => (
<CircleIcon key={i} fill={i < score ? true : false} className={`tw-w-4 tw-h-4`} />
<CircleIcon key={i} fill={i < score ? true : false} className={`tw:w-4 tw:h-4`} />
))}
</div>
)
@ -400,9 +400,9 @@ export const DesignInfo = ({ Link = false, design = false, noDocsLink = false })
}
const makeButton = (
<div className={`tw-grid tw-grid-cols-1 tw-gap-2 tw-mb-4`}>
<div className={`tw:grid tw:grid-cols-1 tw:gap-2 tw:mb-4`}>
<IconButton href={`/editor/#s={"design"%3A"${design}"%2C"view"%3A"draft"}`} color="primary">
<NewPatternIcon className="tw-w-8 tw-h-8" />
<NewPatternIcon className="tw:w-8 tw:h-8" />
New {capitalize(design)} pattern
</IconButton>
</div>
@ -410,9 +410,9 @@ export const DesignInfo = ({ Link = false, design = false, noDocsLink = false })
const buttons = noDocsLink ? (
makeButton
) : (
<div className={`tw-grid tw-grid-cols-1 lg:tw-grid-cols-2 tw-gap-2 tw-mb-4`}>
<div className={`tw:grid tw:grid-cols-1 tw:lg:grid-cols-2 tw:gap-2 tw:mb-4`}>
<IconButton href={`/docs/designs/${design}`} color="secondary">
<DocsIcon className="tw-w-8 tw-h-8" />
<DocsIcon className="tw:w-8 tw:h-8" />
Documentation
</IconButton>
{makeButton}
@ -421,15 +421,15 @@ export const DesignInfo = ({ Link = false, design = false, noDocsLink = false })
return (
<>
<div className="lg:tw-hidden">{buttons}</div>
<div className={`tw-grid tw-grid-cols-1 lg:tw-grid-cols-2 tw-gap-2`}>
<div className="tw-relative">
<div className="tw tw-top-0 tw-left-0">
<div className="tw:lg:hidden">{buttons}</div>
<div className={`tw:grid tw:grid-cols-1 tw:lg:grid-cols-2 tw:gap-2`}>
<div className="tw:relative">
<div className="tw tw:top-0 tw:left-0">
{back ? <LineDrawingBack /> : <LineDrawing />}
</div>
{LineDrawingBack ? (
<button
className="tw-absolute tw-top-2 tw-right-4 tw-start-auto tw-daisy-btn tw-daisy-btn-neutral tw-daisy-btn-outline tw-daisy-btn-xs"
className="tw:absolute tw:top-2 tw:right-4 tw:start-auto tw:daisy-btn tw:daisy-btn-neutral tw:daisy-btn-outline tw:daisy-btn-xs"
onClick={() => setBack(!back)}
>
{back ? 'Front' : 'Back'} view
@ -437,11 +437,11 @@ export const DesignInfo = ({ Link = false, design = false, noDocsLink = false })
) : null}
</div>
<div className="">
<div className="tw-mt-2 tw-text-sm tw-opacity-70 tw-font-medium">Description</div>
<span className="tw-text-xl">{about[design].description}</span>
<div className="tw:mt-2 tw:text-sm tw:opacity-70 tw:font-medium">Description</div>
<span className="tw:text-xl">{about[design].description}</span>
<div className="tw-mt-2 tw-text-sm tw-opacity-70 tw-font-medium">By</div>
<div className="tw-flex tw-flex-row tw-flex-wrap tw-gap-1 items-center">
<div className="tw:mt-2 tw:text-sm tw:opacity-70 tw:font-medium">By</div>
<div className="tw:flex tw:flex-row tw:flex-wrap tw:gap-1 items-center">
{codeBy.map((code) => (
<KeyVal key={code} k="code" val={code} color="secondary" />
))}
@ -450,12 +450,12 @@ export const DesignInfo = ({ Link = false, design = false, noDocsLink = false })
))}
</div>
<div className="tw-mt-2 tw-text-sm tw-opacity-70 tw-font-medium">Difficulty</div>
<div className="tw:mt-2 tw:text-sm tw:opacity-70 tw:font-medium">Difficulty</div>
<Difficulty score={about[design].difficulty} />
{optionalMeasurements[design].length > 0 ? (
<>
<div className="tw-mt-2 tw-text-sm tw-opacity-70 tw-font-medium">
<div className="tw:mt-2 tw:text-sm tw:opacity-70 tw:font-medium">
Optional Measurements
</div>
<div className="">
@ -477,7 +477,7 @@ export const DesignInfo = ({ Link = false, design = false, noDocsLink = false })
{requiredMeasurements[design].length > 0 ? (
<>
<div className="tw-mt-2 tw-text-sm tw-opacity-70 tw-font-medium">
<div className="tw:mt-2 tw:text-sm tw:opacity-70 tw:font-medium">
Required Measurements
</div>
<div className="">
@ -497,24 +497,24 @@ export const DesignInfo = ({ Link = false, design = false, noDocsLink = false })
</>
) : null}
<div className="tw-mt-2 tw-text-sm tw-opacity-70 tw-font-medium">Tags</div>
<div className="tw-flex tw-flex-row tw-flex-wrap tw-gap-1 items-center">
<div className="tw:mt-2 tw:text-sm tw:opacity-70 tw:font-medium">Tags</div>
<div className="tw:flex tw:flex-row tw:flex-wrap tw:gap-1 items-center">
{tags.map((tag) => (
<Link
key={tag}
className="tw-daisy-badge tw-daisy-badge-primary tw-font-medium hover:tw-shadow hover:tw-cursor-pointer"
className="tw:daisy-badge tw:daisy-badge-primary tw:font-medium tw:hover:shadow tw:hover:cursor-pointer"
href={`/designs/#filter={"example"%3Atrue%2C"tag"%3A["${tag}"]}`}
>
{tag}
</Link>
))}
</div>
<div className="tw-mt-2 tw-text-sm tw-opacity-70 tw-font-medium">Techniques</div>
<div className="tw-flex tw-flex-row tw-flex-wrap tw-gap-1 items-center">
<div className="tw:mt-2 tw:text-sm tw:opacity-70 tw:font-medium">Techniques</div>
<div className="tw:flex tw:flex-row tw:flex-wrap tw:gap-1 items-center">
{techniques.map((tech) => (
<Link
key={tech}
className="tw-daisy-badge tw-daisy-badge-accent tw-font-medium hover:tw-shadow hover:tw-cursor-pointer"
className="tw:daisy-badge tw:daisy-badge-accent tw:font-medium tw:hover:shadow tw:hover:cursor-pointer"
href={`/designs/#filter={"example"%3Atrue%2C"tag"%3A["${tech}"]}`}
>
{tech}
@ -522,8 +522,8 @@ export const DesignInfo = ({ Link = false, design = false, noDocsLink = false })
))}
</div>
<div className="tw-mt-2 tw-text-sm tw-opacity-70 tw-font-medium">Examples</div>
<div className="tw-flex tw-flex-row tw-flex-wrap tw-gap-1 items-center">
<div className="tw:mt-2 tw:text-sm tw:opacity-70 tw:font-medium">Examples</div>
<div className="tw:flex tw:flex-row tw:flex-wrap tw:gap-1 items-center">
<KeyVal
k="FreeSewing"
val="showcase"
@ -539,8 +539,8 @@ export const DesignInfo = ({ Link = false, design = false, noDocsLink = false })
/>
</div>
<div className="tw-mt-2 tw-text-sm tw-opacity-70 tw-font-medium">Documentation</div>
<div className="tw-flex tw-flex-row tw-flex-wrap tw-gap-1 items-center">
<div className="tw:mt-2 tw:text-sm tw:opacity-70 tw:font-medium">Documentation</div>
<div className="tw:flex tw:flex-row tw:flex-wrap tw:gap-1 items-center">
<Link href={`/docs/designs/${design}/#notes`}>Designer Notes</Link>,
<Link href={`/docs/designs/${design}/#needs`}>What You Need</Link>,
<Link href={`/docs/designs/${design}/#fabric`}>Fabric Options</Link>,
@ -548,7 +548,7 @@ export const DesignInfo = ({ Link = false, design = false, noDocsLink = false })
<Link href={`/docs/designs/${design}/options/`}>Design Options</Link>,
<Link href={`/docs/designs/${design}/instructions/`}>Sewing Instructions</Link>
</div>
<div className="tw-my-4">{buttons}</div>
<div className="tw:my-4">{buttons}</div>
</div>
</div>
</>
@ -572,391 +572,3 @@ const SharingIsCaring = ({ design }) => (
<p>If you like, you can copy the hashtag below:</p>
</>
)
/*
// __SDEFILE__ - This file is a dependency for the stand-alone environment
// Dependencies
import {
nsMerge,
capitalize,
optionsMenuStructure,
optionType,
cloudflareImageUrl,
horFlexClasses,
} from 'shared/utils.mjs'
import { designs } from 'shared/config/designs.mjs'
import { examples } from 'site/components/design-examples.mjs'
// Hooks
import { useTranslation } from 'next-i18next'
import { useDesign } from 'site/hooks/use-design.mjs'
import { useContext, Fragment } from 'react'
// Context
import { ModalContext } from 'shared/context/modal-context.mjs'
// Components
import { ModalWrapper } from 'shared/components/wrappers/modal.mjs'
import { lineDrawings } from 'shared/components/designs/linedrawings/index.mjs'
import { Difficulty } from 'shared/components/designs/difficulty.mjs'
import { PageLink, AnchorLink, Link } from 'shared/components/link.mjs'
import { DocsLink, DocsTitle } from 'shared/components/mdx/docs-helpers.mjs'
import { Popout } from 'shared/components/popout/index.mjs'
import { NewPatternIcon, DocsIcon } from 'shared/components/icons.mjs'
import { DynamicMdx } from 'shared/components/mdx/dynamic.mjs'
// Translation namespaces used on this page
export const ns = nsMerge(
'account',
'tags',
'techniques',
'measurements',
'workbench',
'designs',
'tags'
)
const Option = ({ id, option, design }) =>
optionType(option) === 'constant' ? null : (
<li key={option.name}>
<DocsLink site="org" slug={`docs/designs/${design}/options/${id.toLowerCase()}`} />
</li>
)
const OptionGroup = ({ id, group, t, design }) => (
<li key={id}>
<b>{t(`workbench:${id}`)}</b>
<ul className="list list-inside list-disc pl-2">
{Object.entries(group).map(([sid, entry]) =>
entry.isGroup ? (
<OptionGroup id={sid} key={sid} t={t} group={entry} design={design} />
) : (
<Option key={sid} id={sid} option={entry} design={design} />
)
)}
</ul>
</li>
)
export const SimpleOptionsList = ({ options, t, design }) => {
const structure = optionsMenuStructure(options, {}, true)
const output = []
for (const [key, entry] of Object.entries(structure)) {
const shared = { key, t, design, id: key }
if (entry.isGroup) output.push(<OptionGroup {...shared} group={entry} />)
else output.push(<Option {...shared} option={entry} />)
}
return <ul className="list list-inside pl-2 list-disc">{output}</ul>
}
export const DesignInfo = ({ design, docs = false, workbench = false, modal = false }) => {
const { setModal } = useContext(ModalContext)
const { t, i18n } = useTranslation([...ns, design])
const { language } = i18n
const Design = useDesign(design)
const config = Design.patternConfig
// Translate measurements
const measies = { required: {}, optional: {} }
if (config?.measurements) {
for (const m of config.measurements) measies.required[m] = t(`measurements:${m}`)
}
if (config?.optionalMeasurements) {
for (const m of config.optionalMeasurements) measies.optional[m] = t(`measurements:${m}`)
}
// Linedrawing
const LineDrawing = lineDrawings[design]
? lineDrawings[design]
: ({ className }) => <div className={className}></div>
// Docs content
const docsContent = (
<>
<h2 id="docs">{t('account:docs')}</h2>
<ul className="list list-disc list-inside pl-2">
<li>
<DocsLink site="org" slug={`docs/designs/${design}`} />
</li>
<li>
<DocsLink site="org" slug={`docs/designs/${design}/cutting`} />
</li>
<li>
<DocsLink site="org" slug={`docs/designs/${design}/instructions`} />
</li>
<li>
<DocsLink site="org" slug={`docs/designs/${design}/needs`} />
</li>
<li>
<DocsLink site="org" slug={`docs/designs/${design}/fabric`} />
</li>
{Object.keys(config.options).length > 0 ? (
<li>
<DocsLink site="org" slug={`docs/designs/${design}/options`} />
</li>
) : null}
<li>
<DocsLink site="org" slug={`docs/designs/${design}/notes`} />
</li>
</ul>
</>
)
return (
<>
<h5 className="-mt-6 text-accent font-medium">#FreeSewing{capitalize(design)}</h5>
<p className="text-xl">{t(`designs:${design}.d`)}</p>
<div className="grid grid-cols-1 lg:grid-cols-2 gap-2">
{workbench ? null : (
<Link
className={`${horFlexClasses} btn btn-primary btn-lg flex md:hidden`}
href={`/new/${design}`}
>
<NewPatternIcon className="w-8 h-8" />
{t('tags:newThingPattern', { thing: capitalize(design) })}
</Link>
)}
{docs ? null : (
<Link
className={`${horFlexClasses} btn btn-secondary btn-lg flex md:hidden`}
href={`/docs/designs/${design}`}
>
<DocsIcon className="w-8 h-8" />
{t('account:docs')}
</Link>
)}
</div>
{docs || workbench || modal ? null : (
<div className="flex flex-row flex-wrap gap-2 md:gap-4 items-center p-4 border rounded-lg bg-secondary bg-opacity-5 max-w-4xl">
<b>Jump to:</b>
<AnchorLink id="notes">
<DocsTitle
slug={`docs/designs/${design}/notes`}
language={language}
format={(t) => t.split(':').pop().trim()}
/>
</AnchorLink>
{examples && <AnchorLink id="examples" txt={t('acount:examples')} />}
{['needs', 'fabric'].map((page) => (
<AnchorLink id={page} key={page}>
<DocsTitle
slug={`docs/designs/${design}/${page}`}
language={language}
format={(t) => t.split(':').pop().trim()}
/>
</AnchorLink>
))}
<AnchorLink id="docs" txt={t('account:docs')} />
<AnchorLink id="specs" txt={t('account:specifications')} />
</div>
)}
<div className={`mt-8 w-full ${docs ? '' : 'flex flex-row flex-wrap justify-between'}`}>
<div className={`w-full max-w-2xl ${docs ? '' : 'md:w-2/3 pr-0 md:pr-8'}`}>
<LineDrawing className="w-full text-base-content" />
{docs ? null : (
<>
<h2 id="notes">
<DocsTitle
slug={`docs/designs/${design}/notes`}
language={language}
format={(t) => t.split(':').pop().trim()}
/>
</h2>
<DynamicMdx
site="org"
slug={`docs/designs/${design}/notes`}
language={language}
title={false}
/>
</>
)}
{docs ? docsContent : null}
{examples ? (
<>
<h2 id="examples">{t('account:examples')}</h2>
{examples[design] ? (
<div className="grid grid-cols-2 gap-2 md:grid-cols-3 lg:grid-cols-3">
{examples[design].map((ex) => (
<button
key={ex}
onClick={() =>
setModal(
<ModalWrapper
flex="col"
justify="top lg:justify-center"
slideFrom="right"
>
<img
className="w-full shadow rounded-lg"
src={cloudflareImageUrl({ id: `showcase-${ex}`, variant: 'public' })}
/>
<p className="text-center">
<PageLink href={`/showcase/${ex}`} txt={t('account:visitShowcase')} />
</p>
</ModalWrapper>
)
}
>
<img
className="w-full shadow rounded-lg"
src={cloudflareImageUrl({ id: `showcase-${ex}`, variant: 'sq500' })}
/>
</button>
))}
</div>
) : (
<Popout note>
<h5>{t('account:noExamples')}</h5>
<p>{t('account:noExamplesMsg')}</p>
<p className="text-right">
<Link className="btn btn-primary" href="/new/showcase">
{t('account:showcaseNew')}
</Link>
</p>
</Popout>
)}
</>
) : null}
{docs
? null
: ['needs', 'fabric'].map((page) => (
<Fragment key={page}>
<h2 id={page}>
<DocsTitle
slug={`docs/designs/${design}/${page}`}
language={language}
format={(t) => t.split(':').pop().trim()}
/>
</h2>
<DynamicMdx
site="org"
slug={`docs/designs/${design}/${page}`}
language={language}
title={false}
/>
</Fragment>
))}
{docs ? null : docsContent}
</div>
<div className={`w-full ${docs ? '' : 'md:w-1/3'}`}>
{workbench ? null : (
<Link
className={`${horFlexClasses} btn btn-primary btn-lg hidden md:flex mb-2`}
href={`/new/${design}`}
>
<NewPatternIcon className="w-8 h-8" />
{t('tags:newThingPattern', { thing: capitalize(design) })}
</Link>
)}
{docs ? null : (
<Link
className={`${horFlexClasses} btn btn-secondary btn-lg hidden md:flex`}
href={`/docs/designs/${design}`}
>
<DocsIcon className="w-8 h-8" />
{t('account:docs')}
</Link>
)}
<h2 id="specs">{t('account:specifications')}</h2>
<h6 className="mt-4">{t('account:design')}</h6>
<ul>
{designs[design].design.map((person) => (
<li key={person}>{person}</li>
))}
</ul>
<h6 className="mt-4">{t('account:code')}</h6>
<ul>
{designs[design].code.map((person) => (
<li key={person}>{person}</li>
))}
</ul>
<h6 className="mt-4">{t('tags:difficulty')}</h6>
<Difficulty score={designs[design].difficulty} />
<h6 className="mt-4">{t('tags:tags')}</h6>
<div className="flex flex-row flex-wrap items-center gap-1">
{designs[design].tags.map((tag) => (
<span className="badge badge-primary font-medium" key={tag}>
{t(`tags:${tag}`)}
</span>
))}
</div>
<h6 className="mt-4">{t('techniques:techniques')}</h6>
<div className="flex flex-row flex-wrap items-center gap-1">
{designs[design].techniques.map((tech) => (
<span className="badge badge-accent font-medium" key={tech}>
{t(`techniques:${tech}`)}
</span>
))}
</div>
{Object.keys(measies.required).length > 0 ? (
<>
<h6 className="mt-4">{t('account:requiredMeasurements')}</h6>
<ul className="list list-disc list-inside pl-2">
{Object.keys(measies.required)
.sort()
.map((m) => (
<li key={m}>
<PageLink
href={`/docs/measurements/${m.toLowerCase()}`}
txt={measies.required[m]}
/>
</li>
))}
</ul>
</>
) : null}
{Object.keys(measies.optional).length > 0 ? (
<>
<h6 className="mt-4">{t('account:optionalMeasurements')}</h6>
<ul className="list list-disc list-inside pl-2">
{Object.keys(measies.optional)
.sort()
.map((m) => (
<li key={m}>
<PageLink
href={`/docs/measurements/${m.toLowerCase()}`}
txt={measies.optional[m]}
/>
</li>
))}
</ul>
</>
) : null}
{Object.keys(config.options).length > 0 ? (
<>
<h6 className="mt-4">{t('account:designOptions')}</h6>
<SimpleOptionsList options={config.options} t={t} design={design} />
</>
) : null}
<h6 className="mt-4">{t('account:parts')}</h6>
<ul className="list list-disc list-inside pl-2">
{config.draftOrder.map((part) => (
<li key={part}>{part}</li>
))}
</ul>
{Object.keys(config.plugins).length > 0 ? (
<>
<h6 className="mt-4">{t('account:plugins')}</h6>
<ul className="list list-disc list-inside pl-2">
{Object.keys(config.plugins).map((plugin) => (
<li key={plugin}>{plugin}</li>
))}
</ul>
</>
) : null}
</div>
</div>
</>
)
}
*/

View file

@ -4,11 +4,11 @@ import { BulletIcon } from '@freesewing/react/components/Icon'
export const ControlScore = ({ control, color = 'base-content' }) =>
control ? (
<div className={`tw-flex tw-flex-row tw-items-center tw-text-${color}`}>
<div className={`tw:flex tw:flex-row tw:items-center tw:text-${color}`}>
{Object.keys(controlDesc).map((score) => (
<BulletIcon
fill={control >= score ? true : false}
className="tw-w-6 tw-h-6 tw--ml-1"
className="tw:w-6 tw:h-6 tw:-ml-1"
key={score}
/>
))}

View file

@ -25,20 +25,20 @@ export const CopyToClipboardButton = ({ children, content, label = false, sup =
const [copied, setCopied] = useState(false)
const { setLoadingStatus } = useContext(LoadingStatusContext)
const style = sup ? 'tw-w-4 tw-h-4 tw--mt-4' : 'tw-w-5 tw-h-5'
const style = sup ? 'tw:w-4 tw:h-4 tw:-mt-4' : 'tw:w-5 tw:h-5'
return (
<button
className={(copied ? 'tw-text-success ' : '') + 'tw-daisy-btn tw-w-full lg:tw-w-auto'}
className={(copied ? 'tw:text-success ' : '') + 'tw:daisy-btn tw:w-full tw:lg:w-auto'}
onClick={() => handleCopied(content, setCopied, setLoadingStatus, label)}
>
{copied ? (
<OkIcon
className={`${style} tw-text-success-content tw-bg-success tw-rounded-full tw-p-1`}
className={`${style} tw:text-success-content tw:bg-success tw:rounded-full tw:p-1`}
stroke={4}
/>
) : (
<CopyIcon className={`${style} tw-text-inherit`} />
<CopyIcon className={`${style} tw:text-inherit`} />
)}
{children}
</button>

View file

@ -45,9 +45,9 @@ export const CuratedSetLineup = ({ href = false, clickHandler = false, Link = fa
return (
<div
className={`tw-w-full tw-flex tw-flex-row ${
sets.length > 1 ? 'tw-justify-start tw-px-8' : 'tw-justify-center'
} tw-overflow-x-scroll`}
className={`tw:w-full tw:flex tw:flex-row ${
sets.length > 1 ? 'tw:justify-start tw:px-8' : 'tw:justify-center'
} tw:overflow-x-scroll`}
style={{
backgroundImage: `url(/img/lineup-backdrop.svg)`,
width: 'auto',
@ -58,7 +58,7 @@ export const CuratedSetLineup = ({ href = false, clickHandler = false, Link = fa
{sets.map((set) => {
const props = {
className:
'tw-aspect-[1/3] tw-w-auto tw-h-96 tw-bg-transparent tw-border-0 hover:tw-cursor-pointer hover:tw-bg-secondary/20',
'tw:aspect-1/3 tw:w-auto tw:h-96 tw:bg-transparent tw:border-0 tw:hover:cursor-pointer tw:hover:bg-secondary/20',
style: {
backgroundImage: `url(${cloudflareImageUrl({
id: `cset-${set.id}`,
@ -73,7 +73,7 @@ export const CuratedSetLineup = ({ href = false, clickHandler = false, Link = fa
}
return (
<div className="tw-flex tw-flex-col tw-items-center" key={set.id}>
<div className="tw:flex tw:flex-col tw:items-center" key={set.id}>
{typeof clickHandler === 'function' ? (
<button {...props} onClick={() => clickHandler(set)}></button>
) : null}
@ -118,14 +118,14 @@ export const CuratedSet = ({ Link = false, id = false }) => {
return (
<>
<h2 className="tw-flex tw-flex-row tw-items-center tw-gap-2">
<h2 className="tw:flex tw:flex-row tw:items-center tw:gap-2">
{set.nameEn} <KeyVal k="id" val={set.id} />
</h2>
<Markdown>{set.notesEn}</Markdown>
<h2>Image</h2>
<img src={cloudflareImageUrl({ id: `cset-${set.id}`, variant: 'public' })} />
<h2>Measurements</h2>
<table className="tw-table">
<table className="tw:table">
<thead>
<tr>
<th>Measurement</th>
@ -144,7 +144,7 @@ export const CuratedSet = ({ Link = false, id = false }) => {
'asc'
).map((entry) => (
<tr key={entry.id}>
<td className="tw-text-right">{entry.t}</td>
<td className="tw:text-right">{entry.t}</td>
<td>{isDegreeMeasurement(entry.id) ? `${entry.val}°` : formatMm(entry.val)}</td>
<td
dangerouslySetInnerHTML={{

View file

@ -88,7 +88,7 @@ export const DesignCard = ({ name, lineDrawing = false }) => {
>
<h5
className={`text-center py-2 px-4 rounded-t-lg m-0 w-full
${lineDrawing ? '' : 'bg-neutral text-neutral-content bg-opacity-70'}`}
${lineDrawing ? '' : 'bg-neutral/70 text-neutral-content'}`}
>
{t(`designs:${name}.t`)}
</h5>
@ -97,11 +97,7 @@ export const DesignCard = ({ name, lineDrawing = false }) => {
</div>
<div
className={`pt-0 m-0 -mt-2 text-center w-full
${
lineDrawing
? 'bg-transparent text-base-content'
: 'bg-neutral text-neutral-content bg-opacity-70'
}`}
${lineDrawing ? 'bg-transparent text-base-content' : 'bg-neutral/70 text-neutral-content'}`}
></div>
</div>
</button>

View file

@ -120,12 +120,12 @@ const AccountNavbarItem = ({ Link }) => {
const SimpleNavbarItem = ({ label, Icon, href, Link }) => (
<Link
className="tw-daisy-btn tw-daisy-btn-ghost hover:tw-no-underline hover:tw-text-base-content custom-navbar-item"
className="tw:daisy-btn tw:daisy-btn-ghost tw:hover:no-underline tw:hover:text-base-content custom-navbar-item no-hover-decoration"
href={href}
>
<div className="tw-flex tw-flex-row tw-gap-2 tw-items-center">
<Icon className="tw-w-6 tw-h-6" />
<span className="tw-text-lg">{label}</span>
<div className="tw:flex tw:flex-row tw:gap-2 tw:items-center">
<Icon className="tw:w-6 tw:h-6 tw:text-base-content" />
<span className="tw:text-lg tw:text-base-content">{label}</span>
</div>
</Link>
)

View file

@ -5,19 +5,15 @@ import React, { useState } from 'react'
* So instead, we handle this in React state
*/
const getProps = (isActive = false) => ({
className: `tw-p-2 tw-px-4 tw-rounded-lg tw-bg-transparent tw-shadow hover:tw-cursor-pointer
tw-w-full tw-h-auto tw-content-start tw-text-left tw-bg-opacity-20
${isActive ? 'hover:tw-bg-transparent' : 'hover:tw-bg-secondary hover:tw-bg-opacity-10'}`,
className: `tw:p-2 tw:px-4 tw:rounded-lg tw:bg-transparent tw:shadow tw:hover:cursor-pointer
tw:w-full tw:h-auto tw:content-start tw:text-left
${isActive ? 'tw:hover:bg-transparent' : 'tw:hover:bg-secondary/10'}`,
})
const getSubProps = (isActive) => ({
className: `tw-p-2 tw-px-4 tw-rounded-none tw-bg-transparent tw-w-full tw-h-auto
tw-content-start tw-bg-secondary tw-text-left tw-bg-opacity-20
${
isActive
? 'tw-bg-opacity-100 hover:tw-bg-transparent tw-shadow'
: 'hover:tw-bg-opacity-10 hover:tw-bg-secondary '
}`,
className: `tw:p-2 tw:px-4 tw:rounded-none tw:bg-transparent tw:w-full tw:h-auto
tw:content-start tw:bg-secondary/20 tw:text-left
${isActive ? 'tw:bg-secondary tw:hover:bg-transparent tw:shadow' : 'tw:hover:bg-secondary/10 '}`,
})
const components = {
@ -43,7 +39,7 @@ export const BaseAccordion = ({
<div key={i} {...propsGetter(true)}>
<Component
onClick={setActive}
className="tw-w-full tw-bg-transparent tw-border-0 hover:tw-bg-secondary hover:tw-bg-opacity-20 hover:tw-cursor-pointer"
className="tw:w-full tw:bg-transparent tw:border-0 tw:hover:bg-secondary/20 tw:hover:cursor-pointer"
>
{item[0]}
</Component>

View file

@ -11,7 +11,7 @@ export const AsideViewMenuButton = ({
}) => {
const className = `w-full flex flex-row items-center px-4 py-2 ${extraClasses} ${
active
? 'font-bold lg:font-normal bg-secondary bg-opacity-10 lg:bg-secondary lg:text-secondary-content lg:bg-opacity-50'
? 'font-bold lg:font-normal bg-secondary/10 lg:bg-secondary/50 lg:text-secondary-content'
: 'lg:bg-neutral lg:text-neutral-content'
}`
const span = <span className="block grow text-left">{label}</span>

View file

@ -31,7 +31,7 @@ const flagIcons = {
warning: WarningIcon,
}
export const FlagTypeIcon = ({ type, className = 'tw-w-6 tw-h-6' }) => {
export const FlagTypeIcon = ({ type, className = 'tw:w-6 tw:h-6' }) => {
const Icon = flagIcons[type] || FixmeIcon
return <Icon className={className} />
@ -39,14 +39,14 @@ export const FlagTypeIcon = ({ type, className = 'tw-w-6 tw-h-6' }) => {
export const Flag = ({ data, handleUpdate, strings }) => {
const btnIcon = data.suggest?.icon ? (
<FlagTypeIcon type={data.suggest.icon} className="tw-w-5 tw-h-6 sm:tw-w-6 tw-h-6" />
<FlagTypeIcon type={data.suggest.icon} className="tw:w-5 tw:h-6 tw:sm:w-6 tw:h-6" />
) : null
const button =
data.suggest?.text && data.suggest?.update ? (
<button
className={`tw-daisy-btn tw-daisy-btn-secondary tw-daisy-btn-outline tw-flex tw-flex-row tw-items-center ${
btnIcon ? 'tw-gap-6' : ''
className={`tw:daisy-btn tw:daisy-btn-secondary tw:daisy-btn-outline tw:flex tw:flex-row tw:items-center ${
btnIcon ? 'tw:gap-6' : ''
}`}
onClick={() => handleUpdate(data.suggest.update)}
>
@ -75,8 +75,8 @@ export const Flag = ({ data, handleUpdate, strings }) => {
: null
return (
<div className="tw-flex tw-flex-col tw-gap-2 tw-items-start">
<div className="first:tw-mt-0 tw-grow md flag tw-flex tw-flex-col tw-gap-2">
<div className="tw:flex tw:flex-col tw:gap-2 tw:items-start">
<div className="tw:first:mt-0 tw:grow md flag tw:flex tw:flex-col tw:gap-2">
{desc ? (
<MiniTip>
<Markdown>{strings[desc] || desc}</Markdown>
@ -89,7 +89,7 @@ export const Flag = ({ data, handleUpdate, strings }) => {
) : null}
</div>
{button ? (
<div className="tw-mt-2 tw-w-full tw-flex tw-flex-row tw-justify-end">{button}</div>
<div className="tw:mt-2 tw:w-full tw:flex tw:flex-row tw:justify-end">{button}</div>
) : null}
</div>
)
@ -102,11 +102,11 @@ export const FlagsAccordionTitle = ({ flags }) => {
return (
<>
<h5 className="tw-flex tw-flex-row tw-gap-2 tw-items-center tw-justify-between tw-w-full">
<span className="tw-text-left">Flags ({Object.keys(flagList).length})</span>
<FlagTypeIcon className="tw-w-8 tw-h-8" />
<h5 className="tw:flex tw:flex-row tw:gap-2 tw:items-center tw:justify-between tw:w-full">
<span className="tw:text-left">Flags ({Object.keys(flagList).length})</span>
<FlagTypeIcon className="tw:w-8 tw:h-8" />
</h5>
<p className="tw-text-left">
<p className="tw:text-left">
{Object.keys(flagList).length > 1
? 'Some issues about your current pattern need your attention.'
: 'A specific issue about your current pattern needs your attention.'}
@ -131,14 +131,14 @@ export const FlagsAccordionEntries = ({ flags, update, pattern, strings }) => {
const title = flag.replace ? mustache.render(flag.title, flag.replace) : flag.title
return [
<div className="tw-w-full tw-flex tw-flex-row tw-gap2 tw-justify-between" key={i}>
<div className="tw-flex tw-flex-row tw-items-center tw-gap-2">
<div className="tw-no-shrink">
<div className="tw:w-full tw:flex tw:flex-row tw:gap2 tw:justify-between" key={i}>
<div className="tw:flex tw:flex-row tw:items-center tw:gap-2">
<div className="tw:no-shrink">
<FlagIcon type={flag.type} />
</div>
<span className="tw-font-medium tw-text-left">{strings[title] || title}</span>
<span className="tw:font-medium tw:text-left">{strings[title] || title}</span>
</div>
<span className="tw-uppercase tw-font-bold">{flag.type}</span>
<span className="tw:uppercase tw:font-bold">{flag.type}</span>
</div>,
<Flag key={key} data={flag} strings={strings} handleUpdate={handleUpdate} />,
key,

View file

@ -61,7 +61,7 @@ export const HeaderMenuIcon = (props) => {
// FIXME: Remove this when ready
if (!headerMenuIcons[name]) console.log('FIXME: Add headerMenuIcon for ', name)
return <Icon {...props} className={`tw-h-5 tw-w-5 ${extraClasses}`} />
return <Icon {...props} className={`tw:h-5 tw:w-5 ${extraClasses}`} />
}
export const HeaderMenuDraftView = (props) => {
@ -70,7 +70,7 @@ export const HeaderMenuDraftView = (props) => {
return (
<>
<div className="tw-flex tw-flex-row tw-gap-0.5 lg:tw-gap-1">
<div className="tw:flex tw:flex-row tw:gap-0.5 tw:lg:gap-1">
<HeaderMenuDraftViewDesignOptions {...props} i18n={i18n} />
<HeaderMenuDraftViewCoreSettings {...props} i18n={i18n} />
<HeaderMenuDraftViewUiPreferences {...props} i18n={i18n} />
@ -103,8 +103,8 @@ export const HeaderMenuTestViewDesignOptions = (props) => {
tooltip="See how design options influence the pattern being generated."
toggle={
<>
<HeaderMenuIcon name="options" extraClasses="tw-text-secondary" />
<span className="tw-hidden lg:tw-inline">Test Options</span>
<HeaderMenuIcon name="options" extraClasses="tw:text-secondary" />
<span className="tw:hidden tw:lg:inline">Test Options</span>
</>
}
>
@ -121,8 +121,8 @@ export const HeaderMenuTestViewDesignMeasurements = (props) => {
tooltip="See how changes to a measurment influence the pattern being generated."
toggle={
<>
<HeaderMenuIcon name="options" extraClasses="tw-text-secondary" />
<span className="tw-hidden lg:tw-inline">Test Measurements</span>
<HeaderMenuIcon name="options" extraClasses="tw:text-secondary" />
<span className="tw:hidden tw:lg:inline">Test Measurements</span>
</>
}
>
@ -145,7 +145,7 @@ export const HeaderMenuDropdown = (props) => {
disabled
tabIndex={0}
role="button"
className={`tw-daisy-btn tw-daisy-btn-ghost hover:tw-bg-secondary hover:tw-bg-opacity-20 hover:tw-border-solid hover:tw-border-2 hover:tw-border-secondary tw-border tw-border-secondary tw-border-2 tw-border-dotted tw-daisy-btn-sm tw-px-2 tw-z-20 tw-relative`}
className={`tw:daisy-btn tw:daisy-btn-ghost tw:hover:bg-secondary/20 tw:hover:border-solid tw:hover:border-2 tw:hover:border-secondary tw:border tw:border-secondary tw:border-2 tw:border-dotted tw:daisy-btn-sm tw:px-2 tw:z-20 tw:relative`}
>
{toggle}
</button>
@ -153,26 +153,26 @@ export const HeaderMenuDropdown = (props) => {
) : (
<Tooltip tip={tooltip}>
<div
className={`tw-daisy-dropdown ${open === id ? 'tw-daisy-dropdown-open tw-z-20' : ''} ${end ? ' tw-daisy-dropdown-end' : ''}`}
className={`tw:daisy-dropdown ${open === id ? 'tw:daisy-dropdown-open tw:z-20' : ''} ${end ? ' tw:daisy-dropdown-end' : ''}`}
>
<div
tabIndex={0}
role="button"
className="tw-daisy-btn tw-daisy-btn-ghost hover:tw-bg-secondary hover:tw-bg-opacity-20 tw-border-secondary/10 hover:tw-border-2 hover:tw-border-secondary tw-border tw-border-secondary tw-border-2 tw-border-solid tw-daisy-btn-sm tw-px-2 tw-z-20 tw-relative"
className="tw:daisy-btn tw:daisy-btn-ghost tw:hover:bg-secondary/20 tw:border-secondary/10 tw:hover:border-2 tw:hover:border-secondary tw:border tw:border-secondary tw:border-2 tw:border-solid tw:daisy-btn-sm tw:px-2 tw:z-20 tw:relative"
onClick={() => setOpen(open === id ? false : id)}
>
{toggle}
</div>
<div
tabIndex={0}
className="tw-daisy-dropdown-content tw-bg-base-100 tw-bg-opacity-90 tw-z-20 tw-shadow tw-left-0 !tw-fixed md:!tw-absolute tw-top-12 tw-w-screen md:tw-max-w-md tw-overflow-y-scroll tw-mb-12 tw-h-fit"
className="tw:daisy-dropdown-content tw:bg-base-100/90 tw:z-20 tw:shadow tw:left-0 tw:fixed! tw:md:absolute! tw:top-12 tw:w-screen tw:md:max-w-md tw:overflow-y-scroll tw:mb-12 tw:h-fit"
style={{ maxHeight: 'calc(100vh - 12rem)' }}
>
{props.children}
</div>
{open === id && (
<div
className="tw-w-screen tw-h-screen tw-absolute tw-top-10 tw-left-0 tw-opacity-0"
className="tw:w-screen tw:h-screen tw:absolute tw:top-10 tw:left-0 tw:opacity-0"
style={{ width: '200vw', transform: 'translateX(-100vw)' }}
onClick={() => setOpen(false)}
></div>
@ -189,8 +189,8 @@ export const HeaderMenuDraftViewDesignOptions = (props) => (
tooltip="These options are specific to this design. You can use them to customize your pattern in a variety of ways."
toggle={
<>
<HeaderMenuIcon name="options" extraClasses="tw-text-secondary" />
<span className="tw-hidden lg:tw-inline tw-capitalize">
<HeaderMenuIcon name="options" extraClasses="tw:text-secondary" />
<span className="tw:hidden tw:lg:inline tw:capitalize">
{props.state.design ? props.state.design : 'Design'} Options
</span>
</>
@ -208,8 +208,8 @@ export const HeaderMenuDraftViewCoreSettings = (props) => {
id="coreSettings"
toggle={
<>
<HeaderMenuIcon name="settings" extraClasses="tw-text-secondary" />
<span className="tw-hidden lg:tw-inline">Core Settings</span>
<HeaderMenuIcon name="settings" extraClasses="tw:text-secondary" />
<span className="tw:hidden tw:lg:inline">Core Settings</span>
</>
}
>
@ -226,8 +226,8 @@ export const HeaderMenuDraftViewUiPreferences = (props) => {
id="uiPreferences"
toggle={
<>
<HeaderMenuIcon name="ui" extraClasses="tw-text-secondary" />
<span className="tw-hidden lg:tw-inline">UI Preferences</span>
<HeaderMenuIcon name="ui" extraClasses="tw:text-secondary" />
<span className="tw:hidden tw:lg:inline">UI Preferences</span>
</>
}
>
@ -246,8 +246,8 @@ export const HeaderMenuDraftViewFlags = (props) => {
id="flags"
toggle={
<>
<HeaderMenuIcon name="flag" extraClasses="tw-text-secondary" />
<span className="tw-hidden lg:tw-inline">
<HeaderMenuIcon name="flag" extraClasses="tw:text-secondary" />
<span className="tw:hidden tw:lg:inline">
Flags
<span>({count})</span>
</span>
@ -262,8 +262,8 @@ export const HeaderMenuDraftViewFlags = (props) => {
export const HeaderMenuDraftViewIcons = (props) => {
const { update, state } = props
const Button = HeaderMenuButton
const size = 'tw-w-5 tw-h-5'
const muted = 'tw-text-current tw-opacity-50'
const size = 'tw:w-5 tw:h-5'
const muted = 'tw:text-current tw:opacity-50'
const ux = state.ui.ux
const levels = {
...props.config.uxLevels.core,
@ -271,14 +271,14 @@ export const HeaderMenuDraftViewIcons = (props) => {
}
return (
<div className="tw-hidden lg:tw-flex tw-flex-row tw-flex-wrap tw-items-center tw-justify-center tw-px-0.5 lg:tw-px-1">
<div className="tw:hidden tw:lg:flex tw:flex-row tw:flex-wrap tw:items-center tw:justify-center tw:px-0.5 tw:lg:px-1">
{ux >= levels.sa ? (
<Button
lgOnly
updateHandler={update.toggleSa}
tooltip="Turns Seam Allowance on or off (see Core Settings)"
>
<SaIcon className={`${size} ${state.settings.sabool ? 'tw-text-secondary' : muted}`} />
<SaIcon className={`${size} ${state.settings.sabool ? 'tw:text-secondary' : muted}`} />
</Button>
) : null}
{ux >= levels.units ? (
@ -291,7 +291,7 @@ export const HeaderMenuDraftViewIcons = (props) => {
>
<UnitsIcon
className={`${size} ${
state.settings.units === 'imperial' ? 'tw-text-secondary' : muted
state.settings.units === 'imperial' ? 'tw:text-secondary' : muted
}`}
/>
</Button>
@ -303,7 +303,7 @@ export const HeaderMenuDraftViewIcons = (props) => {
tooltip="Turns Paperless on or off (see Core Settings)"
>
<PaperlessIcon
className={`${size} ${state.settings.paperless ? 'tw-text-secondary' : muted}`}
className={`${size} ${state.settings.paperless ? 'tw:text-secondary' : muted}`}
/>
</Button>
) : null}
@ -314,7 +314,7 @@ export const HeaderMenuDraftViewIcons = (props) => {
tooltip="Turns Details on or off (see Core Settings)"
>
<DetailIcon
className={`${size} ${!state.settings.complete ? 'tw-text-secondary' : muted}`}
className={`${size} ${!state.settings.complete ? 'tw:text-secondary' : muted}`}
/>
</Button>
) : null}
@ -325,7 +325,7 @@ export const HeaderMenuDraftViewIcons = (props) => {
tooltip="Turns Expand on or off (see Core Settings)"
>
<ExpandIcon
className={`${size} ${state.settings.expand ? 'tw-text-secondary' : muted}`}
className={`${size} ${state.settings.expand ? 'tw:text-secondary' : muted}`}
/>
</Button>
) : null}
@ -336,7 +336,7 @@ export const HeaderMenuDraftViewIcons = (props) => {
updateHandler={() => update.ui('aside', state.ui.aside ? 0 : 1)}
tooltip="Toggles the side menu (see UI Preferences)"
>
<AsideIcon className={`${size} ${state.ui.aside ? 'tw-text-secondary' : muted}`} />
<AsideIcon className={`${size} ${state.ui.aside ? 'tw:text-secondary' : muted}`} />
</Button>
) : null}
{ux >= levels.renderer ? (
@ -348,7 +348,7 @@ export const HeaderMenuDraftViewIcons = (props) => {
tooltip="Switches the Render Engine between React and SVG (see UI Preferences)"
>
<RocketIcon
className={`${size} ${state.ui.renderer === 'svg' ? 'tw-text-secondary' : muted}`}
className={`${size} ${state.ui.renderer === 'svg' ? 'tw:text-secondary' : muted}`}
/>
</Button>
) : null}
@ -359,18 +359,18 @@ export const HeaderMenuDraftViewIcons = (props) => {
export const HeaderMenuUndoIcons = (props) => {
const { update, state, Design } = props
const Button = HeaderMenuButton
const size = 'tw-w-5 tw-h-5'
const size = 'tw:w-5 tw:h-5'
const undos = state._?.undos && state._.undos.length > 0 ? state._.undos : false
return (
<div className="tw-flex tw-flex-row tw-flex-wrap tw-items-center tw-justify-center tw-px-0.5 lg:tw-px-1">
<div className="tw:flex tw:flex-row tw:flex-wrap tw:items-center tw:justify-center tw:px-0.5 tw:lg:px-1">
<Button
lgOnly
updateHandler={() => update.restore(0, state._)}
tooltip="Undo the most recent change"
disabled={undos ? false : true}
>
<UndoIcon className={`${size} ${undos ? 'tw-text-secondary' : ''}`} text="1" />
<UndoIcon className={`${size} ${undos ? 'tw:text-secondary' : ''}`} text="1" />
</Button>
<Button
lgOnly
@ -378,7 +378,7 @@ export const HeaderMenuUndoIcons = (props) => {
tooltip="Undo all changes since the last save point"
disabled={undos ? false : true}
>
<UndoIcon className={`${size} ${undos ? 'tw-text-secondary' : ''}`} text="A" />
<UndoIcon className={`${size} ${undos ? 'tw:text-secondary' : ''}`} text="A" />
</Button>
<HeaderMenuDropdown
end
@ -388,13 +388,13 @@ export const HeaderMenuUndoIcons = (props) => {
disabled={undos ? false : true}
toggle={
<>
<UndoIcon className="tw-w-4 tw-h-4" stroke={3} />
<span className="tw-hidden lg:tw-inline">Undo</span>
<UndoIcon className="tw:w-4 tw:h-4" stroke={3} />
<span className="tw:hidden tw:lg:inline">Undo</span>
</>
}
>
{undos ? (
<ul className="tw-daisy-dropdown-content tw-bg-base-100 tw-bg-opacity-90 tw-z-20 tw-shadow tw-left-0 !tw-fixed md:!tw-absolute tw-w-screen md:tw-w-96 tw-px-4 md:tw-p-2 md:tw-pt-0 tw-contents">
<ul className="tw:daisy-dropdown-content tw:bg-base-100/90 tw:z-20 tw:shadow tw:left-0 tw:fixed! tw:md:absolute! tw:w-screen tw:md:w-96 tw:px-4 tw:md:p-2 tw:md:pt-0 tw:contents">
{undos.slice(0, 9).map((step, index) => (
<li key={index}>
<UndoStep {...{ step, update, state, Design, index }} compact />
@ -402,9 +402,9 @@ export const HeaderMenuUndoIcons = (props) => {
))}
<li key="view">
<ButtonFrame dense onClick={() => update.view('undos')}>
<div className="tw-flex tw-flex-row tw-items-center tw-align-center tw-justify-between tw-gap-2 tw-w-full">
<div className="tw-flex tw-flex-row tw-items-center tw-align-start tw-gap-2 tw-grow">
<UndoIcon className="tw-w-5 tw-h-5 tw-text-secondary" />
<div className="tw:flex tw:flex-row tw:items-center tw:align-center tw:justify-between tw:gap-2 tw:w-full">
<div className="tw:flex tw:flex-row tw:items-center tw:align-start tw:gap-2 tw:grow">
<UndoIcon className="tw:w-5 tw:h-5 tw:text-secondary" />
{viewLabels.undos.t}
</div>
{undos.length}
@ -418,10 +418,10 @@ export const HeaderMenuUndoIcons = (props) => {
updateHandler={update.clearPattern}
tooltip="Reset all settings, but keep the design and measurements"
>
<TrashIcon className={`${size} tw-text-secondary`} />
<TrashIcon className={`${size} tw:text-secondary`} />
</Button>
<Button updateHandler={update.clearAll} tooltip="Reset the editor completely">
<ResetAllIcon className={`${size} tw-text-secondary`} />
<ResetAllIcon className={`${size} tw:text-secondary`} />
</Button>
</div>
)
@ -430,11 +430,11 @@ export const HeaderMenuUndoIcons = (props) => {
export const HeaderMenuTestIcons = (props) => {
const { update, state, Design } = props
const Button = HeaderMenuButton
const size = 'tw-w-5 tw-h-5'
const size = 'tw:w-5 tw:h-5'
const undos = state._?.undos && state._.undos.length > 0 ? state._.undos : false
return (
<div className="tw-flex tw-flex-row tw-flex-wrap tw-items-center tw-justify-center tw-px-0.5 lg:tw-px-1">
<div className="tw:flex tw:flex-row tw:flex-wrap tw:items-center tw:justify-center tw:px-0.5 tw:lg:px-1">
<Button
updateHandler={() => update.settings('sample', undefined)}
tooltip="Clear the test so you can select another"
@ -449,7 +449,7 @@ export const HeaderMenuSaveIcons = (props) => {
const { update, state } = props
const backend = useBackend()
const Button = HeaderMenuButton
const size = 'tw-w-5 tw-h-5'
const size = 'tw:w-5 tw:h-5'
const saveable = state._?.undos && state._.undos.length > 0
/*
@ -473,22 +473,22 @@ export const HeaderMenuSaveIcons = (props) => {
}
return (
<div className="tw-flex tw-flex-row tw-flex-wrap tw-items-center tw-justify-center tw-px-2">
<div className="tw:flex tw:flex-row tw:flex-wrap tw:items-center tw:justify-center tw:px-2">
<Button updateHandler={savePattern} tooltip="Save pattern" disabled={saveable ? false : true}>
<SaveIcon className={`${size} ${saveable ? 'tw-text-success' : ''}`} />
<SaveIcon className={`${size} ${saveable ? 'tw:text-success' : ''}`} />
</Button>
<Button updateHandler={() => update.view('save')} tooltip="Save pattern as...">
<SaveAsIcon className={`${size} tw-text-secondary`} />
<SaveAsIcon className={`${size} tw:text-secondary`} />
</Button>
<Button updateHandler={() => update.view('export')} tooltip="Export pattern">
<ExportIcon className={`${size} tw-text-secondary`} />
<ExportIcon className={`${size} tw:text-secondary`} />
</Button>
</div>
)
}
export const HeaderMenuIconSpacer = () => (
<span className="tw-hidden lg:tw-inline tw-px-1 tw-font-bold tw-opacity-30">|</span>
<span className="tw:hidden tw:lg:inline tw:px-1 tw:font-bold tw:opacity-30">|</span>
)
export const HeaderMenuButton = ({
@ -500,7 +500,7 @@ export const HeaderMenuButton = ({
}) => (
<Tooltip tip={tooltip}>
<button
className={`${lgOnly ? 'tw-hidden lg:tw-inline' : ''} tw-daisy-btn tw-daisy-btn-ghost tw-daisy-btn-sm tw-px-1 disabled:tw-bg-transparent`}
className={`${lgOnly ? 'tw:hidden tw:lg:inline' : ''} tw:daisy-btn tw:daisy-btn-ghost tw:daisy-btn-sm tw:px-1 tw:disabled:bg-transparent`}
onClick={updateHandler}
disabled={disabled}
>
@ -533,19 +533,17 @@ export const HeaderMenuViewMenu = (props) => {
output.push(
<li
key={i}
className="tw-mb-1 tw-flex tw-flex-row tw-items-center tw-justify-between tw-w-full"
className="tw:mb-1 tw:flex tw:flex-row tw:items-center tw:justify-between tw:w-full"
>
<a
className={`tw-w-full tw-text-base-content
tw-flex tw-flex-row tw-items-center tw-gap-2 md:tw-gap-4 tw-p-2 tw-px-4
hover:tw-cursor-pointer hover:tw-text-base-content
hover:tw-bg-secondary hover:tw-bg-opacity-20 ${
viewName === state.view ? 'tw-bg-secondary tw-bg-opacity-20' : ''
}`}
className={`tw:w-full tw:text-base-content
tw:flex tw:flex-row tw:items-center tw:gap-2 tw:md:gap-4 tw:p-2 tw:px-4
tw:hover:cursor-pointer tw:hover:text-base-content
tw:hover:bg-secondary/20 ${viewName === state.view ? 'tw:bg-secondary/20' : ''}`}
onClick={() => update.view(viewName)}
>
<ViewIcon view={viewName} className="tw-w-6 tw-h-6 tw-grow-0" />
<span className="tw-text-left tw-grow tw-font-medium">
<ViewIcon view={viewName} className="tw:w-6 tw:h-6 tw:grow-0" />
<span className="tw:text-left tw:grow tw:font-medium">
{viewLabels[viewName]?.t || viewName}
</span>
</a>
@ -561,8 +559,8 @@ export const HeaderMenuViewMenu = (props) => {
id="views"
toggle={
<>
<HeaderMenuIcon name="right" stroke={3} extraClasses="tw-text-secondary tw-rotate-90" />
<span className="tw-hidden lg:tw-inline">
<HeaderMenuIcon name="right" stroke={3} extraClasses="tw:text-secondary tw:rotate-90" />
<span className="tw:hidden tw:lg:inline">
{viewLabels[state.view] ? viewLabels[state.view].t : 'Views'}
</span>
</>
@ -570,7 +568,7 @@ export const HeaderMenuViewMenu = (props) => {
>
<ul
tabIndex={i}
className="tw-daisy-dropdown-content tw-bg-base-100 tw-bg-opacity-95 tw-z-20 tw-shadow tw-left-0 !tw-fixed md:!tw-absolute tw-w-screen md:tw-max-w-lg md:tw-pt-0 tw-mt-14 md:tw-mt-0 tw-contents"
className="tw:daisy-dropdown-content tw:bg-base-100/95tw:z-20 tw:shadow tw:left-0 tw:fixed! tw:md:absolute! tw:w-screen tw:md:max-w-lg tw:md:pt-0 tw:mt-14 tw:md:mt-0 tw:contents"
>
{output}
</ul>
@ -586,8 +584,8 @@ export const HeaderMenuLayoutView = (props) => (
tooltip="These options are specific to this design. You can use them to customize your pattern in a variety of ways."
toggle={
<>
<HeaderMenuIcon name="layout" extraClasses="tw-text-secondary" />
<span className="tw-hidden lg:tw-inline">Print Settings</span>
<HeaderMenuIcon name="layout" extraClasses="tw:text-secondary" />
<span className="tw:hidden tw:lg:inline">Print Settings</span>
</>
}
>
@ -642,10 +640,10 @@ export const HeaderMenuLayoutViewIcons = (props) => {
return (
<>
<Tooltip tip="Number of pages required for the current layout">
<span className="tw-px-1 tw-font-bold tw-text-sm tw-block tw-h-8 tw-py-1 tw-opacity-80">
<span className="tw:px-1 tw:font-bold tw:text-sm tw:block tw:h-8 tw:py-1 tw:opacity-80">
<span className="">
{count} pages
<span className="tw-pl-1 tw-text-xs tw-font-medium">
<span className="tw:pl-1 tw:text-xs tw:font-medium">
({cols}x{rows}, {blank} blank)
</span>
</span>
@ -653,7 +651,7 @@ export const HeaderMenuLayoutViewIcons = (props) => {
</Tooltip>
<Tooltip tip="Apply this layout to the pattern">
<button
className="tw-daisy-btn tw-daisy-btn-ghost tw-daisy-btn-sm tw-px-1 disabled:tw-bg-transparent tw-text-secondary"
className="tw:daisy-btn tw:daisy-btn-ghost tw:daisy-btn-sm tw:px-1 tw:disabled:bg-transparent tw:text-secondary"
onClick={applyLayout}
disabled={!layoutValid}
>
@ -662,7 +660,7 @@ export const HeaderMenuLayoutViewIcons = (props) => {
</Tooltip>
<Tooltip tip="Generate a PDF that you can print">
<button
className="tw-daisy-btn tw-daisy-btn-ghost tw-daisy-btn-sm tw-px-1 disabled:tw-bg-transparent tw-text-secondary"
className="tw:daisy-btn tw:daisy-btn-ghost tw:daisy-btn-sm tw:px-1 tw:disabled:bg-transparent tw:text-secondary"
onClick={() => update.view('export')}
>
<PrintIcon />
@ -670,7 +668,7 @@ export const HeaderMenuLayoutViewIcons = (props) => {
</Tooltip>
<Tooltip tip="Reset the custom layout">
<button
className="tw-daisy-btn tw-daisy-btn-ghost tw-daisy-btn-sm tw-px-1 disabled:tw-bg-transparent tw-text-secondary"
className="tw:daisy-btn tw:daisy-btn-ghost tw:daisy-btn-sm tw:px-1 tw:disabled:bg-transparent tw:text-secondary"
onClick={resetLayout}
>
<ResetIcon />
@ -705,12 +703,12 @@ export const HeaderMenu = ({ config, Design, pattern, state, update, strings })
return (
<div
className={`tw-flex tw-sticky tw-top-0 ${
state.ui.kiosk ? 'tw-z-50' : 'tw-z-20'
} tw-transition-[top] tw-duration-300 tw-ease-in-out`}
className={`tw:flex tw:sticky tw:top-0 ${
state.ui.kiosk ? 'tw:z-50' : 'tw:z-20'
} tw:transition-[top] tw:duration-300 tw:ease-in-out`}
>
<div
className={`tw-flex tw-flex-row tw-flex-wrap tw-gap-0.5 lg:tw-gap-1 tw-w-full tw-items-start tw-justify-center tw-py-1 md:tw-py-1.5`}
className={`tw:flex tw:flex-row tw:flex-wrap tw:gap-0.5 tw:lg:gap-1 tw:w-full tw:items-start tw:justify-center tw:py-1 tw:md:py-1.5`}
>
<HeaderMenuViewMenu {...{ config, state, update, open, setOpen, strings }} />
<ViewSpecificMenu {...{ config, state, update, Design, pattern, open, setOpen, strings }} />

View file

@ -36,13 +36,13 @@ export const LoadingStatus = ({ state, update }) => {
if (!state._.loading || Object.keys(state._.loading).length < 1) return null
const colorClasses = {
info: 'tw-bg-info tw-text-info-content',
primary: 'tw-bg-primary tw-text-primary-content',
info: 'tw:bg-info tw:text-info-content',
primary: 'tw:bg-primary tw:text-primary-content',
}
return (
<div className="tw-fixed tw-bottom-4 md:tw-buttom-28 tw-left-0 tw-w-full tw-z-30 md:tw-px-4 md:tw-mx-auto mb-4">
<div className="tw-flex tw-flex-col tw-gap-2">
<div className="tw:fixed tw:bottom-4 md:tw:buttom-28 tw:left-0 tw:w-full tw:z-30 tw:md:px-4 tw:md:mx-auto mb-4">
<div className="tw:flex tw:flex-col tw:gap-2">
{Object.entries(state._.loading).map(([id, custom]) => {
const conf = {
...config.defaults,
@ -52,20 +52,20 @@ export const LoadingStatus = ({ state, update }) => {
return (
<div
key={id}
className={`tw-w-full md:tw-max-w-2xl tw-m-auto tw-bg-${
className={`tw:w-full tw:md:max-w-2xl tw:m-auto tw:bg-${
conf.color
} tw-text-${conf.color}-content tw-flex tw-flex-row tw-items-center tw-gap-4 tw-p-4 tw-px-4 ${
conf.fading ? 'tw-opacity-0' : 'tw-opacity-100'
} tw:text-${conf.color}-content tw:flex tw:flex-row tw:items-center tw:gap-4 tw:p-4 tw:px-4 ${
conf.fading ? 'tw:opacity-0' : 'tw:opacity-100'
}
tw-transition-opacity tw-delay-[${config.timeout * 1000 - 400}ms] tw-duration-300
md:tw-rounded-lg tw-shadow tw-text-secondary-content tw-text-lg lg:tw-text-xl tw-font-medium md:tw-bg-opacity-90
${conf.color === 'info' ? 'tw-text-neutral' : ''}
tw:transition-opacity tw:delay-[${config.timeout * 1000 - 400}ms] tw:duration-300
tw:md:rounded-lg tw:shadow tw:text-secondary-content tw:text-lg tw:lg:text-xl tw:font-medium
${conf.color === 'info' ? 'tw:text-neutral' : ''}
`}
>
<span className={`tw-shrink-0 tw-text-${conf.color}-content`}>
<span className={`tw:shrink-0 tw:text-${conf.color}-content`}>
<Icon />
</span>
<div className={conf.color === 'info' ? 'tw-text-neutral tw-w-full' : 'tw-w-full'}>
<div className={conf.color === 'info' ? 'tw:text-neutral tw:w-full' : 'tw:w-full'}>
{conf.msg}
</div>
</div>

View file

@ -21,7 +21,7 @@ export const MeasurementsEditor = ({ Design, update, state, helpProvider = false
}
return (
<div className="tw-max-w-2xl tw-mx-auto">
<div className="tw:max-w-2xl tw:mx-auto">
<h4>Required Measurements</h4>
{Object.keys(Design.patternConfig.measurements).length === 0 ? (
<p>This design does not require any measurements.</p>

View file

@ -407,8 +407,8 @@ const Button = ({ onClickCb, transform, Icon, children, title = '' }) => {
<g transform={transform} className="svg-layout-button group">
<title>{title}</title>
<rect width={rectSize} height={rectSize} className="button" rx="2" ry="2" />
<Icon className="group-hover:tw-text-primary-content" />
<rect width={rectSize} height={rectSize} onClick={_onClick} className="tw-fill-transparent" />
<Icon className="tw:group-hover:text-primary-content" />
<rect width={rectSize} height={rectSize} onClick={_onClick} className="tw:fill-transparent" />
</g>
)
}

View file

@ -30,20 +30,20 @@ export const PatternLayout = (props) => {
return (
<ZoomContextProvider>
<div className="tw-flex tw-flex-col tw-h-full">
<div className="tw:flex tw:flex-col tw:h-full">
<HeaderMenu
state={props.state}
{...{ update, Design, pattern, config, strings: props.strings }}
/>
<div className="tw-flex lg:tw-flex-row tw-grow lg:tw-max-h-[90vh] tw-max-h-[calc(100vh-3rem)] tw-h-full tw-py-2 lg:tw-mt-2">
<div className="lg:tw-w-2/3 tw-flex tw-flex-col tw-h-full tw-grow tw-p-2 tw-shadow tw-mx-2">
<div className="tw:flex tw:lg:flex-row tw:grow tw:lg:max-h-[90vh] tw:max-h-[calc(100vh-3rem)] tw:h-full tw:py-2 tw:lg:mt-2">
<div className="tw:lg:w-2/3 tw:flex tw:flex-col tw:h-full tw:grow tw:p-2 tw:shadow tw:mx-2">
{props.output}
</div>
{state.ui?.aside ? (
<div
className={`tw-hidden xl:tw-block tw-w-1/3 tw-shrink tw-grow-0 lg:tw-p-4 tw-max-w-2xl tw-h-full tw-overflow-scroll`}
className={`tw:hidden tw:xl:block tw:w-1/3 tw:shrink tw:grow-0 tw:lg:p-4 tw:max-w-2xl tw:h-full tw:overflow-scroll`}
>
<h5 className="tw-capitalize">{pattern.designConfig.data.id} Options</h5>
<h5 className="tw:capitalize">{pattern.designConfig.data.id} Options</h5>
<DesignOptionsMenu {...props} />
<h5>Core Settings</h5>
<CoreSettingsMenu {...props} />

View file

@ -46,7 +46,7 @@ export const UserSetPicker = ({
if (!hasSets)
return (
<div className="tw-w-full tw-max-w-3xl tw-mx-auto">
<div className="tw:w-full tw:max-w-3xl tw:mx-auto">
<Popout tip>
<h5> You do not (yet) have any of your own measurements sets</h5>
<p>
@ -56,14 +56,14 @@ export const UserSetPicker = ({
{config.hrefNewSet ? (
<a
href={config.hrefNewSet}
className="tw-daisy-btn tw-daisy-btn-accent tw-capitalize"
className="tw:daisy-btn tw:daisy-btn-accent tw:capitalize"
target="_BLANK"
rel="nofollow"
>
Create a new measurements set
</a>
) : null}
<p className="tw-text-sm">
<p className="tw:text-sm">
Because our patterns are bespoke, we strongly suggest you take accurate measurements.
</p>
</Popout>
@ -73,7 +73,7 @@ export const UserSetPicker = ({
return (
<>
{okSets.length > 0 && (
<div className="tw-grid tw-grid-cols-2 md:tw-grid-cols-4 lg:tw-grid-cols-6 tw-gap-2 tw-mt-4">
<div className="tw:grid tw:grid-cols-2 tw:md:grid-cols-4 tw:lg:grid-cols-6 tw:gap-2 tw:mt-4">
{okSets.map((set) => (
<MsetCard
href={false}
@ -87,13 +87,13 @@ export const UserSetPicker = ({
</div>
)}
{lackingSets.length > 0 ? (
<div className="tw-my-4">
<div className="tw:my-4">
<Popout note>
<h5>
Some of your measurements sets lack the measurements required to generate this pattern
</h5>
</Popout>
<div className="tw-grid tw-grid-cols-2 md:tw-grid-cols-4 lg:tw-grid-cols-6 tw-gap-2">
<div className="tw:grid tw:grid-cols-2 tw:md:grid-cols-4 tw:lg:grid-cols-6 tw:gap-2">
{lackingSets.map((set) => (
<MsetCard
{...{ set, Design }}
@ -154,7 +154,7 @@ export const BookmarkedSetPicker = ({
return (
<>
{okSets.length > 0 && (
<div className="tw-grid tw-grid-cols-2 md:tw-grid-cols-4 lg:tw-grid-cols-6 tw-gap-2">
<div className="tw:grid tw:grid-cols-2 tw:md:grid-cols-4 tw:lg:grid-cols-6 tw:gap-2">
{okSets.map((set) => (
<MsetCard
href={false}
@ -168,14 +168,14 @@ export const BookmarkedSetPicker = ({
</div>
)}
{lackingSets.length > 0 && (
<div className="tw-my-4">
<div className="tw:my-4">
<Popout note>
<h5>
Some of these measurements sets lack the measurements required to generate this
pattern
</h5>
</Popout>
<div className="tw-grid tw-grid-cols-2 md:tw-grid-cols-4 lg:tw-grid-cols-6 tw-gap-2">
<div className="tw:grid tw:grid-cols-2 tw:md:grid-cols-4 tw:lg:grid-cols-6 tw:gap-2">
{lackingSets.map((set) => (
<MsetCard
href={false}
@ -216,7 +216,7 @@ export const CuratedSetPicker = ({ clickHandler }) => {
}, [])
return (
<div className="tw-max-w-7xl">
<div className="tw:max-w-7xl">
<CuratedMeasurementsSetLineup
clickHandler={clickHandler}
sets={orderBy(sets, 'height', 'asc')}
@ -227,9 +227,9 @@ export const CuratedSetPicker = ({ clickHandler }) => {
export const CuratedMeasurementsSetLineup = ({ sets = [], clickHandler }) => (
<div
className={`tw-w-full tw-flex tw-flex-row ${
sets.length > 1 ? 'tw-justify-start tw-px-8' : 'tw-justify-center'
} tw-overflow-x-scroll`}
className={`tw:w-full tw:flex tw:flex-row ${
sets.length > 1 ? 'tw:justify-start tw:px-8' : 'tw:justify-center'
} tw:overflow-x-scroll`}
style={{
backgroundImage: `url(/img/lineup-backdrop.svg)`,
width: 'auto',
@ -240,7 +240,7 @@ export const CuratedMeasurementsSetLineup = ({ sets = [], clickHandler }) => (
{sets.map((set) => {
const props = {
className:
'tw-aspect-[1/3] tw-w-auto tw-h-96 tw-bg-transparent tw-border-0 hover:tw-cursor-pointer hover:tw-bg-secondary/20',
'tw:aspect-1/3 tw:w-auto tw:h-96 tw:bg-transparent tw:border-0 tw:hover:cursor-pointer tw:hover:bg-secondary/20',
style: {
backgroundImage: `url(${cloudflareImageUrl({
id: `cset-${set.id}`,
@ -255,7 +255,7 @@ export const CuratedMeasurementsSetLineup = ({ sets = [], clickHandler }) => (
}
return (
<div className="tw-flex tw-flex-col tw-items-center" key={set.id}>
<div className="tw:flex tw:flex-col tw:items-center" key={set.id}>
<button {...props} key={set.id}></button>
<b>{set.nameEn}</b>
</div>

View file

@ -6,7 +6,7 @@ export const Tooltip = (props) => {
return (
<div
{...rest}
className={`tw-daisy-tooltip tw-daisy-tooltip-bottom before:tw-bg-base-200 before:tw-shadow before:tw-text-base-content`}
className={`tw:daisy-tooltip tw:daisy-tooltip-bottom tw:before:bg-base-200 tw:before:shadow tw:before:text-base-content`}
data-tip={tip}
>
{children}

View file

@ -11,24 +11,24 @@ export const ZoomablePattern = forwardRef(function ZoomablePatternRef(props, ref
const { onTransformed, zoomFunctions, setZoomFunctions } = useContext(ZoomContext)
return (
<div className="tw-relative">
<div className="tw-absolute tw-top-0 tw-right-0 tw-z-20">
<div className="tw-flex tw-flex-row tw-gap-1 tw-items-center">
<div className="tw:relative">
<div className="tw:absolute tw:top-0 tw:right-0 tw:z-20">
<div className="tw:flex tw:flex-row tw:gap-1 tw:items-center">
<button
onClick={() => props.update.ui('rotate', rotate ? 0 : 1)}
className="hover:tw-text-secondary"
className="tw:hover:text-secondary"
>
<RotateIcon className={`tw-h-6 tw-w-6 ${rotate ? 'tw-text-success' : ''}`} />
<RotateIcon className={`tw:h-6 tw:w-6 ${rotate ? 'tw:text-success' : ''}`} />
</button>
<button
onClick={() => (zoomFunctions.zoomIn ? zoomFunctions.zoomIn() : null)}
className="hover:tw-text-secondary"
className="tw:hover:text-secondary"
>
<ZoomInIcon />
</button>
<button
onClick={() => (zoomFunctions.zoomOut ? zoomFunctions.zoomOut() : null)}
className="hover:tw-text-secondary"
className="tw:hover:text-secondary"
>
<ZoomOutIcon />
</button>
@ -53,7 +53,7 @@ export const ZoomablePattern = forwardRef(function ZoomablePatternRef(props, ref
<Pattern
{...{ renderProps, components, strings }}
ref={ref}
className={`freesewing pattern tw-w-full ${rotate ? 'tw--rotate-90' : ''}`}
className={`freesewing pattern tw:w-full ${rotate ? 'tw:-rotate-90' : ''}`}
/>
)}
</TransformComponent>

View file

@ -10,7 +10,7 @@ import { FormControl } from '@freesewing/react/components/Input'
import { MiniTip } from '@freesewing/react/components/Mini'
/** @type {String} class to apply to buttons on open menu items */
const iconButtonClass = 'tw-daisy-btn tw-daisy-btn-xs tw-daisy-btn-ghost tw-px-0 tw-text-accent'
const iconButtonClass = 'tw:daisy-btn tw:daisy-btn-xs tw:daisy-btn-ghost tw:px-0 tw:text-accent'
/**
* A generic component for handling a menu item.
@ -81,15 +81,15 @@ export const MenuItem = ({
}}
>
<EditIcon
className={`tw-w-6 tw-h-6 ${
override ? 'tw-bg-secondary tw-text-secondary-content tw-rounded' : 'tw-text-secondary'
className={`tw:w-6 tw:h-6 ${
override ? 'tw:bg-secondary tw:text-secondary-content tw:rounded' : 'tw:text-secondary'
}`}
/>
</button>
)
const ResetButton = ({ disabled = false }) => (
<button
className={`${iconButtonClass} disabled:tw-bg-opacity-0`}
className={iconButtonClass}
disabled={disabled}
onClick={(evt) => {
evt.stopPropagation()
@ -107,10 +107,10 @@ export const MenuItem = ({
<FormControl
label={false}
id={config.name}
labelBR={<div className="tw-flex tw-flex-row tw-items-center tw-gap-2">{buttons}</div>}
labelBR={<div className="tw:flex tw:flex-row tw:items-center tw:gap-2">{buttons}</div>}
labelBL={
<span
className={`tw-text-base tw-font-medium tw--mt-2 tw-block ${changed ? 'tw-text-accent' : 'tw-opacity-50'}`}
className={`tw:text-base tw:font-medium tw:-mt-2 tw:block ${changed ? 'tw:text-accent' : 'tw:opacity-50'}`}
>
{changed ? 'This is a custom value' : 'This is the default value'}
</span>
@ -190,9 +190,9 @@ export const MenuItemGroup = ({
: () => <span role="img">fixme-icon</span>
const Value = item.isGroup
? () => (
<div className="tw-flex tw-flex-row tw-gap-2 tw-items-center tw-font-medium">
<div className="tw:flex tw:flex-row tw:gap-2 tw:items-center tw:font-medium">
{Object.keys(item).filter((i) => i !== 'isGroup').length}
<OptionsIcon className="tw-w-5 tw-h-5" />
<OptionsIcon className="tw:w-5 tw:h-5" />
</div>
)
: isDesignOptionsGroup
@ -202,14 +202,14 @@ export const MenuItemGroup = ({
: () => <span>¯\_()_/¯</span>
return [
<div className="tw-flex tw-flex-row tw-items-center tw-justify-between tw-w-full" key="a">
<div className="tw-flex tw-flex-row tw-items-center tw-gap-4 tw-w-full">
<div className="tw:flex tw:flex-row tw:items-center tw:justify-between tw:w-full" key="a">
<div className="tw:flex tw:flex-row tw:items-center tw:gap-4 tw:w-full">
<ItemIcon />
<span className="tw-font-medium tw-capitalize">
<span className="tw:font-medium tw:capitalize">
{item.title ? item.title : getItemLabel(i18n, itemName)}
</span>
</div>
<div className="tw-font-bold">
<div className="tw:font-bold">
<Value
current={currentValues[itemName]}
config={item}
@ -275,13 +275,13 @@ export const MenuItemGroup = ({
*/
export const MenuItemTitle = ({ name, current = null, open = false, emoji = '', Icon = false }) => (
<div
className={`tw-flex tw-flex-row tw-gap-1 tw-items-center tw-w-full ${open ? '' : 'tw-justify-between'}`}
className={`tw:flex tw:flex-row tw:gap-1 tw:items-center tw:w-full ${open ? '' : 'tw:justify-between'}`}
>
<span className="tw-font-medium tw-capitalize tw-flex tw-flex-row tw-gap-2">
<span className="tw:font-medium tw:capitalize tw:flex tw:flex-row tw:gap-2">
{Icon ? <Icon /> : <span role="img">{emoji}</span>}
fixme: {name}
</span>
<span className="tw-font-bold">{current}</span>
<span className="tw:font-bold">{current}</span>
</div>
)
@ -318,25 +318,25 @@ export const MenuButtonGroup = ({ structure, Button = false, Design, Icon, i18n
: () => <span role="img">fixme-icon</span>
const Value = item.isGroup
? () => (
<div className="tw-flex tw-flex-row tw-gap-2 tw-items-center tw-font-medium">
<div className="tw:flex tw:flex-row tw:gap-2 tw:items-center tw:font-medium">
{Object.keys(item).filter((i) => i !== 'isGroup').length}
<OptionsIcon className="tw-w-5 tw-h-5" />
<OptionsIcon className="tw:w-5 tw:h-5" />
</div>
)
: null
content.push([
<div
className="tw-flex tw-flex-row tw-items-center tw-justify-between tw-w-full tw-pl-0 tw-pr-4 tw-py-2"
className="tw:flex tw:flex-row tw:items-center tw:justify-between tw:w-full tw:pl-0 tw:pr-4 tw:py-2"
key="a"
>
<div className="tw-flex tw-flex-row tw-items-center tw-gap-4 tw-w-full">
<div className="tw:flex tw:flex-row tw:items-center tw:gap-4 tw:w-full">
<ItemIcon />
<span className="tw-font-medium tw-capitalize">
<span className="tw:font-medium tw:capitalize">
{item.title ? item.title : getItemLabel(i18n, itemName)}
</span>
</div>
<div className="tw-font-bold">
<div className="tw:font-bold">
<Value config={item} Design={Design} />
</div>
</div>,
@ -355,7 +355,7 @@ export const MenuButtonGroup = ({ structure, Button = false, Design, Icon, i18n
}
return (
<div className="tw-flex tw-flex-col tw-gap-0.5 tw-ml-4">
<div className="tw:flex tw:flex-col tw:gap-0.5 tw:ml-4">
{content.filter((item) => item !== null)}
</div>
)

View file

@ -13,19 +13,19 @@ export const DraftMenu = ({ Design, pattern, state, update, i18n }) => {
{
t: 'Design Options',
d: 'These options are specific to this design. You can use them to customize your pattern in a variety of ways.',
icon: <OptionsIcon className="tw-w-8 tw-h-8" />,
icon: <OptionsIcon className="tw:w-8 tw:h-8" />,
menu: <DesignOptionsMenu {...menuProps} />,
},
{
t: 'Core Settings',
d: 'These settings are not specific to the design, but instead allow you to customize various parameters of the FreeSewing core library, which generates the design for you.',
icon: <SettingsIcon className="tw-w-8 tw-h-8" />,
icon: <SettingsIcon className="tw:w-8 tw:h-8" />,
menu: <CoreSettingsMenu {...menuProps} />,
},
{
t: 'UI Preferences',
d: 'These preferences control the UI (User Interface) of the pattern editor',
icon: <UiIcon className="tw-w-8 tw-h-8" />,
icon: <UiIcon className="tw:w-8 tw:h-8" />,
menu: <UiPreferencesMenu {...menuProps} />,
},
]
@ -34,11 +34,11 @@ export const DraftMenu = ({ Design, pattern, state, update, i18n }) => {
items.push(
...sections.map((section) => [
<>
<h5 className="tw-flex tw-flex-row tw-gap-2 tw-items-center tw-justify-between tw-w-full tw-font-bold tw-text-lg">
<h5 className="tw:flex tw:flex-row tw:gap-2 tw:items-center tw:justify-between tw:w-full tw:font-bold tw:text-lg">
<span>{section.t}</span>
{section.icon}
</h5>
<p className="tw-text-left">{section.d}</p>
<p className="tw:text-left">{section.d}</p>
</>,
section.menu,
section.name,

View file

@ -36,8 +36,8 @@ export const MenuConstantInput = ({
<input
type={type}
className={`
tw-daisy-input tw-daisy-input-bordered tw-w-full tw-text-base-content
${changed ? 'tw-daisy-input-secondary' : 'tw-daisy-input-accent'}
tw:daisy-input tw:daisy-input-bordered tw:w-full tw:text-base-content
${changed ? 'tw:daisy-input-secondary' : 'tw:daisy-input-accent'}
`}
value={changed ? current : config.dflt}
onChange={(evt) => updateHandler([name], evt.target.value)}
@ -143,16 +143,16 @@ export const MenuListInput = ({
onClick={() => handleChange(entry)}
>
<div
className={`tw-w-full tw-flex ${
className={`tw:w-full tw:flex ${
sideBySide
? 'tw-flex-row tw-justify-between tw-gap-2 tw-items-center'
: 'tw-flex-col tw-items-start'
? 'tw:flex-row tw:justify-between tw:gap-2 tw:items-center'
: 'tw:flex-col tw:items-start'
}`}
>
<div className="tw-font-semibold">{config.choiceTitles[entry]}</div>
<div className="tw:font-semibold">{config.choiceTitles[entry]}</div>
{compact || !config.choiceDescriptions ? null : (
<div
className={`${config.dense ? 'tw-text-sm tw-leading-5 tw-py-1' : 'tw-text-base'} tw-font-normal`}
className={`${config.dense ? 'tw:text-sm tw:leading-5 tw:py-1' : 'tw:text-base'} tw:font-normal`}
>
{config.choiceDescriptions[entry]}
</div>
@ -178,7 +178,7 @@ export const MenuListToggle = ({ config, changed, updateHandler, name }) => {
return (
<input
type="checkbox"
className={`tw-daisy-toggle ${changed ? 'tw-daisy-toggle-accent' : 'tw-daisy-toggle-secondary'}`}
className={`tw:daisy-toggle ${changed ? 'tw:daisy-toggle-accent' : 'tw:daisy-toggle-secondary'}`}
checked={checked}
onChange={doToggle}
onClick={(evt) => evt.stopPropagation()}
@ -296,7 +296,7 @@ export const MenuSliderInput = ({
if (override)
return (
<>
<div className="tw-flex tw-flex-row tw-justify-between">
<div className="tw:flex tw:flex-row tw:justify-between">
<MenuEditOption
{...{
config,
@ -314,17 +314,17 @@ export const MenuSliderInput = ({
return (
<>
<div className="tw-flex tw-flex-row tw-justify-between">
<span className="tw-opacity-50">
<div className="tw:flex tw:flex-row tw:justify-between">
<span className="tw:opacity-50">
<span dangerouslySetInnerHTML={{ __html: valFormatter(min) + suffix }} />
</span>
<div
className={`tw-font-bold ${val === config.dflt ? 'tw-text-secondary' : 'tw-text-accent'}`}
className={`tw:font-bold ${val === config.dflt ? 'tw:text-secondary' : 'tw:text-accent'}`}
>
<span dangerouslySetInnerHTML={{ __html: valFormatter(val) + suffix }} />
{typeof config.toAbs === 'function' ? (
<span>
<span className="tw-px-2">|</span>
<span className="tw:px-2">|</span>
<span
dangerouslySetInnerHTML={{
__html: formatMm(
@ -340,7 +340,7 @@ export const MenuSliderInput = ({
</span>
) : null}
</div>
<span className="tw-opacity-50">
<span className="tw:opacity-50">
<span dangerouslySetInnerHTML={{ __html: valFormatter(max) + suffix }} />
</span>
</div>
@ -349,8 +349,8 @@ export const MenuSliderInput = ({
{...{ min, max, value: val, step: config.step || 0.1 }}
onChange={(evt) => handleChange(evt.target.value)}
className={`
tw-daisy-range tw-daisy-range-sm tw-mt-1
${changed ? 'tw-daisy-range-accent' : 'tw-daisy-range-secondary'}
tw:daisy-range tw:daisy-range-sm tw:mt-1
${changed ? 'tw:daisy-range-accent' : 'tw:daisy-range-secondary'}
`}
/>
{children}
@ -396,21 +396,21 @@ export const MenuEditOption = (props) => {
return <p>This design option type does not have a component to handle manual input.</p>
return (
<div className="tw-daisy-form-control tw-mb-2 tw-w-full">
<div className="tw-daisy-label tw-font-medium tw-text-accent">
<label className="tw-daisy-label-text">
<div className="tw:daisy-form-control tw:mb-2 tw:w-full">
<div className="tw:daisy-label tw:font-medium tw:text-accent">
<label className="tw:daisy-label-text">
<em>Enter a custom value</em>
</label>
{type === 'pct' && typeof config.fromAbs === 'function' ? (
<label className="tw-daisy-label-text">
<label className="tw:daisy-label-text">
<KeyVal k="units" val={units} onClick={toggleInputUnits} color="secondary" />
</label>
) : null}
</div>
<label className="tw-daisy-input-group tw-daisy-input-group-sm tw-flex tw-flex-row tw-items-end tw-gap-2 tw--mt-4">
<label className="tw:daisy-input-group tw:daisy-input-group-sm tw:flex tw:flex-row tw:items-end tw:gap-2 tw:-mt-4">
<NumberInput value={manualEdit} update={setManualEdit} />
<button
className="tw-daisy-btn tw-daisy-btn-secondary tw-mt-4"
className="tw:daisy-btn tw:daisy-btn-secondary tw:mt-4"
onClick={() => onUpdate(manualEdit, units)}
>
<ApplyIcon />
@ -470,8 +470,8 @@ export const MenuOnlySettingInput = (props) => {
const [design, name] = part.split('.')
config.choiceTitles[part] = (
<span>
<span className="tw-font-medium tw-opacity-80 tw-capitalize">{design}</span>
<span className="tw-font-medium tw-opacity-80 tw-capitalize tw-px-2">&raquo;</span>
<span className="tw:font-medium tw:opacity-80 tw:capitalize">{design}</span>
<span className="tw:font-medium tw:opacity-80 tw:capitalize tw:px-2">&raquo;</span>
{i18n[design].en.p[name]}
</span>
)

View file

@ -29,7 +29,7 @@ export const LayoutSettingsMenu = ({ update, state, Design }) => {
orientation: ({ current, changed }) => (
<MenuHighlightValue changed={changed}>
<PatternIcon
className={`tw-w-6 tw-h-6 tw-text-inherit ${current === 'landscape' ? 'tw--rotate-90' : ''}`}
className={`tw:w-6 tw:h-6 tw:text-inherit ${current === 'landscape' ? 'tw:-rotate-90' : ''}`}
/>
</MenuHighlightValue>
),
@ -67,8 +67,8 @@ const PrintActions = ({ state, update }) => (
<SubAccordion
items={[
[
<div className="tw-w-full tw-flex tw-flex-row tw-gap2 tw-justify-between" key={1}>
<div className="tw-flex tw-flex-row tw-items-center tw-gap-2">
<div className="tw:w-full tw:flex tw:flex-row tw:gap2 tw:justify-between" key={1}>
<div className="tw:flex tw:flex-row tw:items-center tw:gap-2">
<LeftRightIcon />
<span>{'workbench:partTransfo'}</span>
</div>
@ -78,7 +78,7 @@ const PrintActions = ({ state, update }) => (
key={2}
update={() => update.state.ui('hideMovableButtons', state.ui.hideMovableButtons ? false : true)}
label={
<span className="tw-text-base tw-font-normal">{'workbench:partTransfoDesc'}</span>
<span className="tw:text-base tw:font-normal">{'workbench:partTransfoDesc'}</span>
}
list={[
{
@ -97,8 +97,8 @@ const PrintActions = ({ state, update }) => (
'partTransfo',
],
[
<div className="tw-w-full tw-flex tw-flex-row tw-gap2 tw-justify-between" key={1}>
<div className="tw-flex tw-flex-row tw-items-center tw-gap-2">
<div className="tw:w-full tw:flex tw:flex-row tw:gap2 tw:justify-between" key={1}>
<div className="tw:flex tw:flex-row tw:items-center tw:gap-2">
<ResetIcon />
<span>{'workbench:resetPrintLayout'}</span>
</div>
@ -108,7 +108,7 @@ const PrintActions = ({ state, update }) => (
<Fragment key={2}>
<p>{'workbench:resetPrintLayoutDesc'}</p>
<button
className={`${horFlexClasses} tw-btn tw-btn-warning tw-btn-outline tw-w-full`}
className={`${horFlexClasses} tw:btn tw:btn-warning tw:btn-outline tw:w-full`}
onClick={() => update.ui(['layouts', 'print'])}
>
<ResetIcon />

View file

@ -81,12 +81,12 @@ export const TestMeasurementsMenu = ({ Design, state, update }) => {
const SampleOptionButton = ({ name, i18n, update }) => (
<button
className={
'tw-daisy-btn tw-daisy-btn-outline tw-daisy-btn-sm tw-mx-2 ' +
'tw-daisy-btn-secondary tw-flex tw-flex-row tw-items-center tw-justify-between'
'tw:daisy-btn tw:daisy-btn-outline tw:daisy-btn-sm tw:mx-2 ' +
'tw:daisy-btn-secondary tw:flex tw:flex-row tw:items-center tw:justify-between'
}
onClick={() => update.settings('sample', { type: 'option', option: name })}
>
<BeakerIcon className="tw-w-5 tw-h-5" />
<BeakerIcon className="tw:w-5 tw:h-5" />
<span>{i18n.en.o[name].t}</span>
</button>
)
@ -94,12 +94,12 @@ const SampleOptionButton = ({ name, i18n, update }) => (
const SampleMeasurementButton = ({ name, i18n, update }) => (
<button
className={
'tw-daisy-btn tw-daisy-btn-outline tw-daisy-btn-sm tw-mx-2 ' +
'tw-daisy-btn-secondary tw-flex tw-flex-row tw-items-center tw-justify-between'
'tw:daisy-btn tw:daisy-btn-outline tw:daisy-btn-sm tw:mx-2 ' +
'tw:daisy-btn-secondary tw:flex tw:flex-row tw:items-center tw:justify-between'
}
onClick={() => update.settings('sample', { type: 'option', option: name })}
>
<BeakerIcon className="tw-w-5 tw-h-5" />
<BeakerIcon className="tw:w-5 tw:h-5" />
<span>{measurementsTranslations[name]}</span>
</button>
)

View file

@ -50,7 +50,7 @@ export const MenuDegOptionValue = ({ config, current, changed }) => (
* @param {Function} children - The React children
*/
export const MenuHighlightValue = ({ changed, children }) => (
<span className={changed ? 'tw-text-accent' : ''}> {children} </span>
<span className={changed ? 'tw:text-accent' : ''}> {children} </span>
)
/**

View file

@ -9,7 +9,7 @@ import { Collection } from '@freesewing/react/components/Collection'
* @param {Object} update - ViewWrapper state update object
*/
export const DesignsView = ({ designs = {}, update }) => (
<div className="tw-text-center tw-mt-8 tw-mb-24 tw-p-2 lg: tw-p-8">
<div className="tw:text-center tw:mt-8 tw:mb-24 tw:p-2 lg: tw:p-8">
<h1>Choose a design from the FreeSewing collection</h1>
<Collection
editor

View file

@ -19,11 +19,11 @@ export const DocsView = ({ state, config, update }) => {
return (
<>
<HeaderMenu state={state} {...{ config, update }} />
<div className="tw-m-auto tw-mt-8 tw-max-w-2xl tw-px-4 tw-mb-8">
<div className="tw:m-auto tw:mt-8 tw:max-w-2xl tw:px-4 tw:mb-8">
<H1>Documenation</H1>
<Popout link>
<H5>Understanding the FreeSewing Pattern Editor</H5>
<p className="tw-text-lg">
<p className="tw:text-lg">
Please refer to the pattern editor documentation at:
<br />
<b>

View file

@ -33,21 +33,21 @@ export const DraftErrorHandler = ({ failure, errors }) => {
<Link href="https://codeberg.org/freesewing/freesewing/issues">report an issue</Link>.
</p>
<div className={'tw-mt-4'}>
<div className={'tw:mt-4'}>
<button
className={`tw-daisy-btn tw-daisy-btn-primary`}
className={`tw:daisy-btn tw:daisy-btn-primary`}
onClick={() => setExpanded(!expanded)}
>
<ExpandIcon />
Show error details
</button>
<button className={`tw-daisy-btn tw-ml-4`} onClick={() => setHidden(true)}>
<button className={`tw:daisy-btn tw:ml-4`} onClick={() => setHidden(true)}>
<CloseIcon />
Hide
</button>
</div>
{expanded ? (
<div className={'tw-mt-8'}>
<div className={'tw:mt-8'}>
{failure ? <LogEntry key="failure" logEntry={failure} /> : null}
{errors.map((line, i) => (
<LogEntry key={i} logEntry={line} />

View file

@ -65,7 +65,7 @@ export const DraftView = ({ Design, state, update, config, plugins = [], PluginO
<DraftErrorHandler {...{ failure, errors }} />
<PluginOutput {...{ pattern, Design, state, update, config }} />
<ZoomablePattern update={update}>
<div className="tw-w-full tw-h-full" dangerouslySetInnerHTML={{ __html }} />
<div className="tw:w-full tw:h-full" dangerouslySetInnerHTML={{ __html }} />
</ZoomablePattern>
</>
)

View file

@ -27,9 +27,9 @@ export const EditSettingsView = (props) => {
return (
<>
<HeaderMenu state={state} {...{ config, update }} />
<div className="tw-m-auto tw-mt-8 tw-max-w-4xl tw-px-4 tw-mb-8">
<div className="tw:m-auto tw:mt-8 tw:max-w-4xl tw:px-4 tw:mb-8">
<H1>Edit settings by hand</H1>
<p className="tw-mb-4">
<p className="tw:mb-4">
You can hand-edit your pattern settings below.
<br />
The changes will not take effect until you click the <b>Save Settings</b> button at the
@ -106,22 +106,22 @@ export const PrimedSettingsEditor = (props) => {
<>
<H4>You have made changes</H4>
<p>Your settings have been edited, and are now different from the editor settings.</p>
<div className="tw-grid tw-grid-cols-1 lg:tw-grid-cols-3 tw-gap-2 tw-w-full">
<div className="tw:grid tw:grid-cols-1 tw:lg:grid-cols-3 tw:gap-2 tw:w-full">
<button
className="tw-daisy-btn tw-daisy-btn-primary tw-daisy-btn-outline"
className="tw:daisy-btn tw:daisy-btn-primary tw:daisy-btn-outline"
onClick={() => setShowDelta(!showDelta)}
>
{showDelta ? 'Hide' : 'Show'} Changes
</button>
<button
className="tw-daisy-btn tw-daisy-btn-primary tw-flex tw-flex-row tw-items-center tw-justify-between"
className="tw:daisy-btn tw:daisy-btn-primary tw:flex tw:flex-row tw:items-center tw:justify-between"
onClick={save}
>
<OkIcon stroke={3} />
Save Settings
</button>
<button
className="tw-daisy-btn tw-daisy-btn-error tw-daisy-btn-outline tw-flex tw-flex-row tw-items-center tw-justify-between"
className="tw:daisy-btn tw:daisy-btn-error tw:daisy-btn-outline tw:flex tw:flex-row tw:items-center tw:justify-between"
onClick={revert}
>
<ResetIcon />
@ -129,7 +129,7 @@ export const PrimedSettingsEditor = (props) => {
</button>
</div>
{showDelta ? (
<div className="tw-my-4 tw-w-full tw-overflow-scroll">
<div className="tw:my-4 tw:w-full tw:overflow-scroll">
<DiffViewer
oldValue={yaml.stringify(state.settings)}
newValue={yaml.stringify(settings)}

View file

@ -52,11 +52,11 @@ export const ExportView = (props) => {
return (
<>
<HeaderMenu state={state} {...{ config, update }} />
<div className="tw-m-auto tw-mt-8 tw-max-w-2xl tw-px-4 tw-mb-8">
<div className="tw:m-auto tw:mt-8 tw:max-w-2xl tw:px-4 tw:mb-8">
<H1>Export Pattern</H1>
<H2>Share your pattern</H2>
<p>If you merely want to share your pattern with others, you can copy these URLs:</p>
<div className="tw-grid tw-grid-cols-1 lg:tw-grid-cols-2 tw-gap-2 tw-mt-2 ">
<div className="tw:grid tw:grid-cols-1 tw:lg:grid-cols-2 tw:gap-2 tw:mt-2 ">
<CopyToClipboardButton content={urls.a} update={update}>
Pattern and Measurements
</CopyToClipboardButton>
@ -64,11 +64,11 @@ export const ExportView = (props) => {
Pattern only
</CopyToClipboardButton>
</div>
<details className="tw-pt-2">
<details className="tw:pt-2">
<summary>
<span className={linkClasses}>Explain these buttons</span>
</summary>
<div className="tw-ml-4 tw-border-l-2 tw-pl-4">
<div className="tw:ml-4 tw:border-l-2 tw:pl-4">
<H5>Pattern and Measurements</H5>
<p>
Use the <b>Pattern and Measurements</b> URL to share this pattern exactly as-is,
@ -77,8 +77,8 @@ export const ExportView = (props) => {
<Highlight noCopy title="URL" language="URL">
{urls.a}
</Highlight>
<div className="tw-text-sm tw--mt-3 tw-flex tw-flex-row tw-gap-2 tw-items-center tw-pl-4 tw-mb-4">
<TipIcon className="tw-w-5 tw-h-5 tw-text-success" />
<div className="tw:text-sm tw:-mt-3 tw:flex tw:flex-row tw:gap-2 tw:items-center tw:pl-4 tw:mb-4">
<TipIcon className="tw:w-5 tw:h-5 tw:text-success" />
Use this to allow others to troubleshoot your pattern.
</div>
<H5>Pattern only</H5>
@ -88,20 +88,20 @@ export const ExportView = (props) => {
<Highlight noCopy title="URL" language="URL">
{urls.b}
</Highlight>
<div className="tw-text-sm tw--mt-3 tw-flex tw-flex-row tw-gap-2 tw-items-center tw-pl-4">
<TipIcon className="tw-w-5 tw-h-5 tw-text-success" />
<div className="tw:text-sm tw:-mt-3 tw:flex tw:flex-row tw:gap-2 tw:items-center tw:pl-4">
<TipIcon className="tw:w-5 tw:h-5 tw:text-success" />
Use this to allow others to recreate this pattern for themselves.
</div>
</div>
</details>
<H2>Export for printing</H2>
<p>You can export your pattern in a variety of page formats for printing:</p>
<div className="tw-grid tw-grid-cols-1 lg:tw-grid-cols-2 tw-gap-2">
<div className="tw-flex tw-flex-col tw-gap-2 tw-max-w-md">
<div className="tw:grid tw:grid-cols-1 tw:lg:grid-cols-2 tw:gap-2">
<div className="tw:flex tw:flex-col tw:gap-2 tw:max-w-md">
<H3>ISO paper sizes</H3>
{['a4', 'a3', 'a2', 'a1', 'a0'].map((format) => (
<button
className={`${horFlexClasses} tw-daisy-btn tw-daisy-btn-primary tw-uppercase`}
className={`${horFlexClasses} tw:daisy-btn tw:daisy-btn-primary tw:uppercase`}
onClick={() => exportPattern({ ...exportProps, format })}
>
<PrintIcon />
@ -109,11 +109,11 @@ export const ExportView = (props) => {
</button>
))}
</div>
<div className="tw-flex tw-flex-col tw-gap-2 tw-max-w-md">
<div className="tw:flex tw:flex-col tw:gap-2 tw:max-w-md">
<H3>Other paper sizes</H3>
{['letter', 'legal', 'tabloid'].map((format) => (
<button
className={`${horFlexClasses} tw-daisy-btn tw-daisy-btn-primary tw-uppercase`}
className={`${horFlexClasses} tw:daisy-btn tw:daisy-btn-primary tw:uppercase`}
onClick={() => exportPattern({ ...exportProps, format })}
>
<PrintIcon />
@ -126,10 +126,10 @@ export const ExportView = (props) => {
<p>
We recommend SVG for editing, but we also provide a full-sized PDF if you prefer that.
</p>
<div className="tw-grid tw-grid-cols-1 lg:tw-grid-cols-2 tw-gap-2 tw-mt-2">
<div className="tw:grid tw:grid-cols-1 tw:lg:grid-cols-2 tw:gap-2 tw:mt-2">
{['svg', 'pdf'].map((format) => (
<button
className={`${horFlexClasses} tw-daisy-btn tw-daisy-btn-primary tw-uppercase`}
className={`${horFlexClasses} tw:daisy-btn tw:daisy-btn-primary tw:uppercase`}
onClick={() => exportPattern({ ...exportProps, format })}
>
<EditIcon />
@ -139,10 +139,10 @@ export const ExportView = (props) => {
</div>
<H2>Export as code</H2>
<p>This is all you need to reconstruct this pattern using FreeSewing&apos; software:</p>
<div className="tw-grid tw-grid-cols-1 lg:tw-grid-cols-2 tw-gap-2 tw-mt-2">
<div className="tw:grid tw:grid-cols-1 tw:lg:grid-cols-2 tw:gap-2 tw:mt-2">
{['json', 'yaml'].map((format) => (
<button
className={`${horFlexClasses} tw-daisy-btn tw-daisy-btn-primary tw-uppercase`}
className={`${horFlexClasses} tw:daisy-btn tw:daisy-btn-primary tw:uppercase`}
onClick={() => exportPattern({ ...exportProps, format })}
>
<CodeIcon />

View file

@ -68,7 +68,7 @@ export const InspectView = ({ Design, state, update, config }) => {
<Xray
renderProps={renderProps}
drillProps={{ info }}
className={`freesewing pattern tw-w-full ${state.ui?.rotate ? 'tw--rotate-90' : ''}`}
className={`freesewing pattern tw:w-full ${state.ui?.rotate ? 'tw:-rotate-90' : ''}`}
strings={strings}
/>
</ZoomablePattern>

View file

@ -3,7 +3,7 @@ import Markdown from 'react-markdown'
export const LogEntry = ({ logEntry }) => (
<>
<div className="log-entry tw-mb-2">
<div className="log-entry tw:mb-2">
<Markdown>{Array.isArray(logEntry) ? logEntry[0] : logEntry}</Markdown>
</div>
{/* uncomment to enable stacktrace view

View file

@ -26,7 +26,7 @@ export const LogView = (props) => {
return (
<>
<HeaderMenu state={state} {...{ config, update }} />
<div className="tw-m-auto tw-mt-8 tw-max-w-2xl tw-px-4 tw-mb-8">
<div className="tw:m-auto tw:mt-8 tw:max-w-2xl tw:px-4 tw:mb-8">
<H1>Pattern Logs</H1>
<Tabs tabs="Set 0 Logs, Pattern Logs">
<Tab tabId="Set 0 Logs">

View file

@ -22,7 +22,7 @@ import { HeaderMenu } from '../HeaderMenu.mjs'
import { H1, H5 } from '@freesewing/react/components/Heading'
const iconClasses = {
className: 'tw-w-8 tw-h-8 md:tw-w-10 md:tw-h-10 lg:tw-w-12 lg:tw-h-12 tw-shrink-0',
className: 'tw:w-8 tw:h-8 tw:md:w-10 tw:md:h-10 tw:lg:w-12 tw:lg:h-12 tw:shrink-0',
stroke: 1.5,
}
@ -77,13 +77,13 @@ export const MeasurementsView = ({
// User measurement set
update.settings(['metadata'], { setName: set.name })
update.notifySuccess(
<div className="tw-flex tw-flex-row tw-items-center tw-justify-between tw-w-full tw-flex-wrap tw-gap-2">
<div className="tw:flex tw:flex-row tw:items-center tw:justify-between tw:w-full tw:flex-wrap tw:gap-2">
<span>Measurements loaded</span>
<button
className="tw-daisy-btn tw-daisy-btn-success tw-daisy-btn-outline tw-border-white"
className="tw:daisy-btn tw:daisy-btn-success tw:daisy-btn-outline tw:border-white"
onClick={() => update.view('draft')}
>
<span className="tw-text-white">Load Draft View</span>
<span className="tw:text-white">Load Draft View</span>
</button>
</div>
)
@ -95,11 +95,11 @@ export const MeasurementsView = ({
items.push(
[
<Fragment key={1}>
<div className={`${horFlexClasses} tw-w-full`}>
<div className={`${horFlexClasses} tw:w-full`}>
<H5 id="ownsets">Choose one of your own measurements sets</H5>
<MeasurementsSetIcon {...iconClasses} />
</div>
<p className="tw-text-left">
<p className="tw:text-left">
Pick any of your own measurements sets that have all required measurements to generate
this pattern.
</p>
@ -115,11 +115,11 @@ export const MeasurementsView = ({
],
[
<Fragment key={1}>
<div className={`${horFlexClasses} tw-w-full`}>
<div className={`${horFlexClasses} tw:w-full`}>
<H5 id="bookmarkedsets">Choose one of the measurements sets you have bookmarked</H5>
<BookmarkIcon {...iconClasses} />
</div>
<p className="tw-text-left">
<p className="tw:text-left">
If you have bookmarked any measurements sets, you can select from those too.
</p>
</Fragment>,
@ -134,11 +134,11 @@ export const MeasurementsView = ({
],
[
<Fragment key={1}>
<div className={`${horFlexClasses} tw-w-full`}>
<div className={`${horFlexClasses} tw:w-full`}>
<H5 id="curatedsets">Choose one of FreeSewing&apos;s curated measurements sets</H5>
<CuratedMeasurementsSetIcon {...iconClasses} />
</div>
<p className="tw-text-left">
<p className="tw:text-left">
If you&apos;re just looking to try out our platform, you can select from our list of
curated measurements sets.
</p>
@ -148,11 +148,11 @@ export const MeasurementsView = ({
],
[
<Fragment key={1}>
<div className={`${horFlexClasses} tw-w-full`}>
<div className={`${horFlexClasses} tw:w-full`}>
<H5 id="loadid">Load a measurements set by ID</H5>
<FingerprintIcon {...iconClasses} />
</div>
<p className="tw-text-left">
<p className="tw:text-left">
If you know the ID of a measurements set either one of your own or a public set we
can load it for you.
</p>
@ -164,11 +164,11 @@ export const MeasurementsView = ({
// Manual editing is always an option
items.push([
<Fragment key={1}>
<div className={`${horFlexClasses} tw-w-full`}>
<div className={`${horFlexClasses} tw:w-full`}>
<H5 id="editmeasurements">Edit measurements by hand</H5>
<EditIcon {...iconClasses} />
</div>
<p className="tw-text-left">You can manually set or override measurements below.</p>
<p className="tw:text-left">You can manually set or override measurements below.</p>
</Fragment>,
<MeasurementsEditor
key={2}
@ -180,7 +180,7 @@ export const MeasurementsView = ({
return (
<>
<HeaderMenu state={state} {...{ config, update }} />
<div className="tw-max-w-7xl tw-mt-8 tw-mx-auto tw-px-4 tw-mb-4">
<div className="tw:max-w-7xl tw:mt-8 tw:mx-auto tw:px-4 tw:mb-4">
<H1>Measurements</H1>
{missingMeasurements && missingMeasurements.length > 0 ? (
<Popout note dense noP>
@ -188,11 +188,11 @@ export const MeasurementsView = ({
To generate this pattern, we need {missingMeasurements.length} additional measurement
{missingMeasurements.length === 1 ? '' : 's'}:
</h3>
<ol className="tw-list tw-list-inside tw-flex tw-flex-row tw-flex-wrap tw-ml-0 tw-pl-0">
<ol className="tw:list tw:list-inside tw:flex tw:flex-row tw:flex-wrap tw:ml-0 tw:pl-0">
{missingMeasurements.map((m, i) => (
<li key={i} className="tw-flex">
{i > 0 ? <span className="tw-pr-2">,</span> : null}
<span className="tw-font-medium">{measurementsTranslations[m]}</span>
<li key={i} className="tw:flex">
{i > 0 ? <span className="tw:pr-2">,</span> : null}
<span className="tw:font-medium">{measurementsTranslations[m]}</span>
</li>
))}
</ol>
@ -200,15 +200,15 @@ export const MeasurementsView = ({
) : (
<Popout tip dense noP>
<H5>We have all required measurements to draft this pattern</H5>
<div className="tw-flex tw-flex-row tw-flex-wrap tw-gap-2 tw-mt-2">
<div className="tw:flex tw:flex-row tw:flex-wrap tw:gap-2 tw:mt-2">
<button
className="tw-daisy-btn tw-daisy-btn-primary"
className="tw:daisy-btn tw:daisy-btn-primary"
onClick={() => update.view('draft')}
>
Draft Pattern
</button>
<button
className="tw-daisy-btn tw-daisy-btn-primary tw-daisy-btn-outline"
className="tw:daisy-btn tw:daisy-btn-primary tw:daisy-btn-outline"
onClick={() => update.view('picker')}
>
Choose a different view
@ -228,7 +228,7 @@ const LoadMeasurementsSetById = ({ loadMeasurements, update }) => {
return (
<div>
<div className="tw-flex tw-flex-row tw-gap-2 tw-items-end">
<div className="tw:flex tw:flex-row tw:gap-2 tw:items-end">
<NumberInput
label="Measurements Set ID"
update={setId}
@ -236,7 +236,7 @@ const LoadMeasurementsSetById = ({ loadMeasurements, update }) => {
valid={(val) => Number(val) == val}
/>
<button
className="tw-daisy-btn tw-daisy-btn-primary"
className="tw:daisy-btn tw:daisy-btn-primary"
onClick={() => loadMeasurementsSet(id, backend, loadMeasurements, update)}
>
Load set
@ -256,13 +256,13 @@ async function loadMeasurementsSet(id, backend, loadMeasurements, update) {
loadMeasurements(result[1].set)
update.clearLoading()
update.notifySuccess(
<div className="tw-flex tw-flex-row tw-items-center tw-justify-between tw-w-full tw-flex-wrap tw-gap-2">
<div className="tw:flex tw:flex-row tw:items-center tw:justify-between tw:w-full tw:flex-wrap tw:gap-2">
<span>Measurements set loaded</span>
<button
className="tw-daisy-btn tw-daisy-btn-success tw-daisy-btn-outline tw-border-white"
className="tw:daisy-btn tw:daisy-btn-success tw:daisy-btn-outline tw:border-white"
onClick={() => update.view('draft')}
>
<span className="tw-text-white">Load Draft View</span>
<span className="tw:text-white">Load Draft View</span>
</button>
</div>
)

View file

@ -92,7 +92,7 @@ export const SaveView = ({ config, state, update }) => {
return (
<RoleBlock user>
<HeaderMenu state={state} {...{ config, update }} />
<div className="tw-m-auto tw-mt-8 tw-max-w-2xl tw-px-4">
<div className="tw:m-auto tw:mt-8 tw:max-w-2xl tw:px-4">
{saveAs && saveAs.pattern ? (
<>
<h2>Save Pattern</h2>
@ -103,16 +103,16 @@ export const SaveView = ({ config, state, update }) => {
</Popout>
)}
<button
className={`${classeshorFlexNoSm} tw-btn tw-btn-primary tw-btn-lg tw-w-full tw-mt-2 tw-my-8`}
className={`${classeshorFlexNoSm} tw:btn tw:btn-primary tw:btn-lg tw:w-full tw:mt-2 tw:my-8`}
onClick={savePattern}
>
<SaveIcon className="tw-h-8 tw-w-8" />
<SaveIcon className="tw:h-8 tw:w-8" />
Save Patter #{saveAs.pattern}
</button>
</>
) : null}
<H1>Save As New Pattern</H1>
<div className="tw-mb-4">
<div className="tw:mb-4">
<StringInput
label="Pattern title"
current={name}
@ -121,20 +121,20 @@ export const SaveView = ({ config, state, update }) => {
labelBR={
<>
{withNotes ? (
<div className="tw-flex tw-flex-row tw-items-center tw-gap-4">
<div className="tw:flex tw:flex-row tw:items-center tw:gap-4">
<button
className={`tw-font-bold ${linkClasses}`}
className={`tw:font-bold ${linkClasses}`}
onClick={() => setWithNotes(false)}
>
Hide notes
</button>
<button className={`tw-font-bold ${linkClasses}`} onClick={addSettingsToNotes}>
<button className={`tw:font-bold ${linkClasses}`} onClick={addSettingsToNotes}>
Add settings to notes
</button>
</div>
) : (
<button
className={`tw-font-bold ${linkClasses}`}
className={`tw:font-bold ${linkClasses}`}
onClick={() => setWithNotes(true)}
>
Add notes
@ -150,24 +150,24 @@ export const SaveView = ({ config, state, update }) => {
update={setNotes}
/>
) : null}
<div className="tw-flex tw-flex-row tw-gap-2 tw-mt-8">
<div className="tw:flex tw:flex-row tw:gap-2 tw:mt-8">
<button
className={`tw-daisy-btn tw-daisy-btn-primary lg:tw-daisy-btn-lg tw-daisy-btn-outline`}
className={`tw:daisy-btn tw:daisy-btn-primary lg:tw:daisy-btn-lg tw:daisy-btn-outline`}
onClick={update.viewBack}
title="Cancel"
>
<span>Cancel</span>
</button>
<button
className={`tw-flex tw-flex-row tw-items-center tw-justify-between tw-daisy-btn tw-daisy-btn-primary lg:tw-daisy-btn-lg tw-grow`}
className={`tw:flex tw:flex-row tw:items-center tw:justify-between tw:daisy-btn tw:daisy-btn-primary lg:tw:daisy-btn-lg tw:grow`}
onClick={saveAsNewPattern}
title="Save as new pattern"
>
<SaveAsIcon className="tw-w-8 tw-h-8" />
<SaveAsIcon className="tw:w-8 tw:h-8" />
<span>Save as new pattern</span>
</button>
</div>
<p className="tw-text-sm tw-text-right">
<p className="tw:text-sm tw:text-right">
To access your saved patterns, go to:
<b>
{' '}

View file

@ -92,22 +92,22 @@ export const TestView = ({ Design, state, update, config }) => {
return (
<>
<HeaderMenu state={state} {...{ config, update, Design }} />
<div className="tw-m-auto tw-mt-8 tw-max-w-4xl tw-px-4 tw-mb-8">
<div className="tw:m-auto tw:mt-8 tw:max-w-4xl tw:px-4 tw:mb-8">
<H1>Test Pattern</H1>
<div className="tw-grid tw-grid-cols-1 lg:tw-grid-cols-2 lg:tw-gap-4">
<div className="tw-flex tw-flex-col tw-gap-4">
<div className="tw:grid tw:grid-cols-1 tw:lg:grid-cols-2 tw:lg:gap-4">
<div className="tw:flex tw:flex-col tw:gap-4">
<H3>Test Design Options</H3>
<SampleOptionsMenu {...{ Design, state, update }} />
</div>
{trm.length > 0 ? (
<div className="tw-flex tw-flex-col tw-gap-4">
<div className="tw:flex tw:flex-col tw:gap-4">
<H3>Test Measurements</H3>
<H4>Required Measurements</H4>
<div className="">
{trm.map(({ t, m }) => (
<button
key={m}
className="tw-my-0.5 tw-block tw-daisy-btn tw-daisy-btn-primary tw-daisy-btn-outline tw-daisy-btn-xs"
className="tw:my-0.5 tw:block tw:daisy-btn tw:daisy-btn-primary tw:daisy-btn-outline tw:daisy-btn-xs"
onClick={() =>
update.settings(['sample'], { type: 'measurement', measurement: m })
}
@ -117,13 +117,13 @@ export const TestView = ({ Design, state, update, config }) => {
))}
</div>
{tom.length > 0 ? (
<div className="tw-flex tw-flex-col tw-gap-4">
<div className="tw:flex tw:flex-col tw:gap-4">
<H4>Optional Measurements</H4>
<div className="">
{tom.map(({ t, m }) => (
<button
key={m}
className="tw-my-0.5 tw-block tw-daisy-btn tw-daisy-btn-primary tw-daisy-btn-outline tw-daisy-btn-xs"
className="tw:my-0.5 tw:block tw:daisy-btn tw:daisy-btn-primary tw:daisy-btn-outline tw:daisy-btn-xs"
onClick={() =>
update.settings(['sample'], { type: 'measurement', measurement: m })
}
@ -175,7 +175,7 @@ const SampleOptionsSubMenu = ({ structure, update, level = 1 }) => {
output.push(
<button
key={name}
className="tw-my-0.5 tw-block tw-daisy-btn tw-daisy-btn-primary tw-daisy-btn-outline tw-daisy-btn-xs"
className="tw:my-0.5 tw:block tw:daisy-btn tw:daisy-btn-primary tw:daisy-btn-outline tw:daisy-btn-xs"
onClick={() => update.settings(['sample'], { type: 'option', option: name })}
>
{struct.title}
@ -188,7 +188,7 @@ const SampleOptionsSubMenu = ({ structure, update, level = 1 }) => {
if (struct.isGroup) {
output.push(
<H5 key={name}>
<span className="tw-capitalize">{name}</span>
<span className="tw:capitalize">{name}</span>
</H5>
)
output.push(
@ -202,5 +202,5 @@ const SampleOptionsSubMenu = ({ structure, update, level = 1 }) => {
}
}
return <div className="tw-pl-2 tw-border-l-2">{output}</div>
return <div className="tw:pl-2 tw:border-l-2">{output}</div>
}

View file

@ -22,16 +22,16 @@ export const UndosView = ({ Design, update, state, config }) => {
return (
<>
<HeaderMenu {...{ update, Design, config, state }} />
<div className="tw-text-left tw-mt-8 tw-mb-24 tw-px-4 tw-max-w-xl tw-mx-auto">
<div className="tw:text-left tw:mt-8 tw:mb-24 tw:px-4 tw:max-w-xl tw:mx-auto">
<H1>Undo History</H1>
<p className="tw-mb-4">Time-travel through your recent pattern changes.</p>
<p className="tw:mb-4">Time-travel through your recent pattern changes.</p>
{steps.length < 1 ? (
<Popout note>
<h4>Your undo history is currently empty</h4>
<p>When you make changes to your pattern, they will show up here.</p>
<p>For example, you can click the button below to change the pattern rotation:</p>
<button
className="tw-daisy-btn tw-daisy-btn-primary tw-capitalize"
className="tw:daisy-btn tw:daisy-btn-primary tw:capitalize"
onClick={() => update.settings('ui.rotate', state.settings?.ui?.rotate ? 0 : 1)}
>
Example: Rotate pattern
@ -43,7 +43,7 @@ export const UndosView = ({ Design, update, state, config }) => {
<MiniTip>
Click on any change to undo all changes up to, and including, that change.
</MiniTip>
<div className="tw-flex tw-flex-col tw-gap-2 tw-mt-4">
<div className="tw:flex tw:flex-col tw:gap-2 tw:mt-4">
{steps.map((step, index) => (
<UndoStep key={step.time} {...{ step, update, state, Design, index }} />
))}
@ -97,8 +97,8 @@ export const UndoStep = ({ update, state, step, Design, compact = false, index =
if (compact)
return (
<ButtonFrame dense onClick={() => update.restore(index, state._)}>
<div className="tw-flex tw-flex-row tw-items-center tw-align-start tw-gap-2 tw-w-full">
<UndoIcon text={index} className="tw-w-5 tw-h-5 tw-text-secondary" />
<div className="tw:flex tw:flex-row tw:items-center tw:align-start tw:gap-2 tw:w-full">
<UndoIcon text={index} className="tw:w-5 tw:h-5 tw:text-secondary" />
{data.msg ? data.msg : data.title}
</div>
</ButtonFrame>
@ -106,20 +106,20 @@ export const UndoStep = ({ update, state, step, Design, compact = false, index =
return (
<>
<p className="tw-text-sm tw-italic tw-font-medium tw-opacity-70 tw-text-right tw-p-0 tw-tw-m-0 tw--mb-2 tw-pr-2">
<p className="tw:text-sm tw:italic tw:font-medium tw:opacity-70 tw:text-right tw:p-0 tw:tw:m-0 tw:-mb-2 tw:pr-2">
<UndoStepTimeAgo step={step} />
</p>
<ButtonFrame onClick={() => update.restore(index, state._)}>
<div className="tw-flex tw-flex-row tw-items-center tw-justify-between tw-gap-2 tw-w-full tw-m-0 tw-p-0 tw--mt-2 tw-text-lg">
<span className="tw-flex tw-flex-row tw-gap-2 tw-items-center">
<div className="tw:flex tw:flex-row tw:items-center tw:justify-between tw:gap-2 tw:w-full tw:m-0 tw:p-0 tw:-mt-2 tw:text-lg">
<span className="tw:flex tw:flex-row tw:gap-2 tw:items-center">
{data.fieldIcon || null}
{data.title}
</span>
<span className="tw-opacity-70 tw-flex tw-flex-row tw-gap-1 tw-items-center tw-text-base">
<span className="tw:opacity-70 tw:flex tw:flex-row tw:gap-1 tw:items-center tw:text-base">
{data.icon || null} {data.menu}
</span>
</div>
<div className="tw-flex tw-flex-row tw-gap-1 tw-items-center tw-align-start tw-w-full">
<div className="tw:flex tw:flex-row tw:gap-1 tw:items-center tw:align-start tw:w-full">
{data.msg ? (
data.msg
) : (
@ -127,8 +127,8 @@ export const UndoStep = ({ update, state, step, Design, compact = false, index =
<span className="">
{Array.isArray(data.newVal) ? data.newVal.join(', ') : data.newVal}
</span>
<LeftIcon className="tw-w-4 tw-h-4 tw-text-secondary tw-shrink-0" stroke={4} />
<span className="tw-line-through tw-decoration-1 tw-opacity-70">
<LeftIcon className="tw:w-4 tw:h-4 tw:text-secondary tw:shrink-0" stroke={4} />
<span className="tw:line-through tw:decoration-1 tw:opacity-70">
{Array.isArray(data.oldVal) ? data.oldVal.join(', ') : data.oldVal}
</span>
</>

View file

@ -20,16 +20,16 @@ export const ViewPicker = ({ Design, update, state }) => {
*/
if (state._.missingMeasurements.length > 1)
return (
<div className="tw-text-center tw-mt-8 tw-mb-24 tw-px-4 tw-max-w-xl tw-mx-auto">
<div className="tw:text-center tw:mt-8 tw:mb-24 tw:px-4 tw:max-w-xl tw:mx-auto">
<H2>Choose a view</H2>
<div className="tw-flex tw-flex-col tw-mx-auto tw-justify-center tw-gap-2 tw-mt-4">
<div className="tw:flex tw:flex-col tw:mx-auto tw:justify-center tw:gap-2 tw:mt-4">
{config.measurementsFreeViews
.filter((view) => view !== 'picker')
.map((view) => (
<MainCard key={view} {...{ view, update, Design }} />
))}
<Popout note>
<div className="tw-text-left">
<div className="tw:text-left">
<H5>pe:measurementsFreeViewsOnly.t:</H5>
<p>pe:measurementsFreeViewsOnly.d</p>
</div>
@ -39,20 +39,20 @@ export const ViewPicker = ({ Design, update, state }) => {
)
return (
<div className="tw-text-center tw-mt-8 tw-mb-24 tw-px-4">
<div className="tw:text-center tw:mt-8 tw:mb-24 tw:px-4">
<H2>Choose an Editor View</H2>
<div className="tw-max-w-6xl tw-grid tw-grid-cols-1 lg:tw-grid-cols-2 tw-mx-auto tw-justify-center tw-gap-2 lg:tw-gap-4 tw-mt-4">
<div className="tw:max-w-6xl tw:grid tw:grid-cols-1 tw:lg:grid-cols-2 tw:mx-auto tw:justify-center tw:gap-2 tw:lg:gap-4 tw:mt-4">
{config.mainViews.map((view) => (
<MainCard key={view} {...{ view, update, Design }} />
))}
</div>
<div className="tw-max-w-6xl tw-grid tw-grid-cols-1 lg:tw-grid-cols-4 tw-mx-auto tw-justify-center tw-gap-2 lg:tw-gap-4 tw-mt-4">
<div className="tw:max-w-6xl tw:grid tw:grid-cols-1 tw:lg:grid-cols-4 tw:mx-auto tw:justify-center tw:gap-2 tw:lg:gap-4 tw:mt-4">
{config.extraViews.map((view) => (
<ExtraCard key={view} {...{ view, update }} />
))}
</div>
{showDev || state.ui.ux > 3 ? (
<div className="tw-max-w-6xl tw-grid tw-grid-cols-1 lg:tw-grid-cols-4 tw-mx-auto tw-justify-center tw-gap-2 lg:tw-gap-4 tw-mt-4">
<div className="tw:max-w-6xl tw:grid tw:grid-cols-1 tw:lg:grid-cols-4 tw:mx-auto tw:justify-center tw:gap-2 tw:lg:gap-4 tw:mt-4">
{config.devViews.map((view) => (
<ExtraCard key={view} {...{ view, update }} />
))}
@ -60,7 +60,7 @@ export const ViewPicker = ({ Design, update, state }) => {
) : null}
{state.ui.ux < 4 ? (
<button
className="tw-daisy-btn tw-daisy-btn-ghost tw-mt-2"
className="tw:daisy-btn tw:daisy-btn-ghost tw:mt-2"
onClick={() => setShowDev(!showDev)}
>
{showDev ? 'Hide' : 'Show'} Advanced Views
@ -75,19 +75,19 @@ const MainCard = ({ view, update, Design }) => {
return (
<button
className={`tw-border tw-shadow tw-p-4 tw-rounded-lg tw-w-full hover:tw-bg-secondary hover:tw-bg-opacity-20 tw-flex tw-flex-col`}
className={`tw:border tw:shadow tw:p-4 tw:rounded-lg tw:w-full tw:hover:bg-secondary/20 tw:flex tw:flex-col`}
title={viewLabels[view].t}
onClick={() => update.view(view)}
>
<H4>
<div
className={`tw-flex tw-flex-row tw-items-start tw-justify-between tw-p-0 tw-mb-2 tw-text-left`}
className={`tw:flex tw:flex-row tw:items-start tw:justify-between tw:p-0 tw:mb-2 tw:text-left`}
>
<span>{viewLabels[view].t}</span>
<Icon className="tw-w-10 tw-h-10" />
<Icon className="tw:w-10 tw:h-10" />
</div>
</H4>
<p className={`tw-text-left tw-text-lg tw-m-0 tw-p-0 tw-grow-2 tw-font-medium`}>
<p className={`tw:text-left tw:text-lg tw:m-0 tw:p-0 tw:grow-2 tw:font-medium`}>
{viewLabels[view].d}
</p>
</button>
@ -98,17 +98,17 @@ const ExtraCard = ({ view, update }) => {
const Icon = viewIcons[view]
return (
<button
className="tw-border tw-shadow tw-p-3 tw-rounded-lg tw-w-full hover:tw-bg-secondary hover:tw-bg-opacity-20 tw-flex tw-flex-col"
className="tw:border tw:shadow tw:p-3 tw:rounded-lg tw:w-full tw:hover:bg-secondary/20 tw:flex tw:flex-col"
title={viewLabels[view].t}
onClick={() => update.view(view)}
>
<H5>
<div className="tw-flex tw-flex-row tw-items-center tw-justify-between tw-p-0 tw-mb-1 tw-text-left">
<div className="tw:flex tw:flex-row tw:items-center tw:justify-between tw:p-0 tw:mb-1 tw:text-left">
<span>{viewLabels[view].t}</span>
<Icon className="tw-w-8 tw-h-8" />
<Icon className="tw:w-8 tw:h-8" />
</div>
</H5>
<p className="tw-text-left tw-m-0 tw-p-0 tw-grow-2">{viewLabels[view].d}</p>
<p className="tw:text-left tw:m-0 tw:p-0 tw:grow-2">{viewLabels[view].d}</p>
</button>
)
}

View file

@ -72,13 +72,13 @@ export const View = (props) => {
if (view === 'timing') return <TimingView {...props} />
if (view === 'picker') return <ViewPicker {...props} />
return <h1 className="tw-ext-center tw-my-12">No view component for view {props.view}</h1>
return <h1 className="tw:ext-center tw:my-12">No view component for view {props.view}</h1>
}
/*
* This returns a view-specific icon
*/
export const ViewIcon = ({ view, className = 'tw-w-6 tw-h-6' }) => {
export const ViewIcon = ({ view, className = 'tw:w-6 tw:h-6' }) => {
const Icon = viewIcons[view] || FixmeIcon
return <Icon className={className} />

View file

@ -62,7 +62,7 @@ export function menuCoreSettingsSaboolHandler({ toggleSa }) {
}
const CoreDocsLink = ({ item }) => (
<a href={`/docs/about/site/draft/#${item.toLowerCase()}`} className={`${linkClasses} tw-px-2`}>
<a href={`/docs/about/site/draft/#${item.toLowerCase()}`} className={`${linkClasses} tw:px-2`}>
Learn more
</a>
)

View file

@ -7,7 +7,7 @@ import { linkClasses } from '@freesewing/utils'
const DesignDocsLink = ({ design, item }) => (
<a
href={`/docs/designs/${design}/options/#${item.toLowerCase()}`}
className={`${linkClasses} tw-px-2`}
className={`${linkClasses} tw:px-2`}
target="_BLANK"
>
Learn more

View file

@ -10,7 +10,7 @@ import {
} from '@freesewing/react/components/Icon'
const UiDocsLink = ({ item }) => (
<a href={`/docs/about/site/draft/#${item.toLowerCase()}`} className={`${linkClasses} tw-px-2`}>
<a href={`/docs/about/site/draft/#${item.toLowerCase()}`} className={`${linkClasses} tw:px-2`}>
Learn more
</a>
)
@ -63,15 +63,15 @@ export function menuLayoutSettingsStructure(units) {
list: ['portrait', 'landscape'],
choiceTitles: {
portrait: (
<div className="tw-flex tw-flex-row tw-items-center tw-gap-4">
<PatternIcon className="tw-h-5 tw-w-5" />
<span className="tw-grow">Portrait (tall)</span>
<div className="tw:flex tw:flex-row tw:items-center tw:gap-4">
<PatternIcon className="tw:h-5 tw:w-5" />
<span className="tw:grow">Portrait (tall)</span>
</div>
),
landscape: (
<div className="tw-flex tw-flex-row tw-items-center tw-gap-4">
<PatternIcon className="tw-h-5 tw-w-5 tw--rotate-90" />
<span className="tw-grow">Landscape (wide)</span>
<div className="tw:flex tw:flex-row tw:items-center tw:gap-4">
<PatternIcon className="tw:h-5 tw:w-5 tw:-rotate-90" />
<span className="tw:grow">Landscape (wide)</span>
</div>
),
},

View file

@ -4,7 +4,7 @@ import { linkClasses } from '@freesewing/utils'
import { AsideIcon, RotateIcon, RocketIcon, UxIcon } from '@freesewing/react/components/Icon'
const UiDocsLink = ({ item }) => (
<a href={`/docs/about/site/draft/#${item.toLowerCase()}`} className={`${linkClasses} tw-px-2`}>
<a href={`/docs/about/site/draft/#${item.toLowerCase()}`} className={`${linkClasses} tw:px-2`}>
Learn more
</a>
)

View file

@ -1,37 +1,37 @@
import React from 'react'
export const H1 = ({ children }) => (
<h1 className="tw-text-5xl tw-pt-5 tw-pb-4 tw-font-thin tw-tracking-tighter lg:tw-text-6xl">
<h1 className="tw:text-5xl tw:pt-5 tw:pb-4 tw:font-thin tw:tracking-tighter tw:lg:text-6xl">
{children}
</h1>
)
export const H2 = ({ children }) => (
<h2 className="tw-text-3xl tw-pt-4 tw-pb-3 tw-font-black tw-tracking-tighter tw-m-0 lg:tw-text-4xl">
<h2 className="tw:text-3xl tw:pt-4 tw:pb-3 tw:font-black tw:tracking-tighter tw:m-0 tw:lg:text-4xl">
{children}
</h2>
)
export const H3 = ({ children }) => (
<h3 className="tw-text-2xl tw-pt-3 tw-pb-2 tw-font-extrabold tw-m-0 tw-tracking-tighter lg:tw-text-3xl">
<h3 className="tw:text-2xl tw:pt-3 tw:pb-2 tw:font-extrabold tw:m-0 tw:tracking-tighter tw:lg:text-3xl">
{children}
</h3>
)
export const H4 = ({ children }) => (
<h4 className="tw-text-xl tw-pt-2 tw-pb-1 tw-font-bold tw-m-0 tw-tracking-tighter lg:tw-text-2xl">
<h4 className="tw:text-xl tw:pt-2 tw:pb-1 tw:font-bold tw:m-0 tw:tracking-tighter tw:lg:text-2xl">
{children}
</h4>
)
export const H5 = ({ children }) => (
<h5 className="tw-text-lg tw-py-1 tw-font-semibold tw-m-0 tw-tracking-tight lg:tw-text-xl">
<h5 className="tw:text-lg tw:py-1 tw:font-semibold tw:m-0 tw:tracking-tight tw:lg:text-xl">
{children}
</h5>
)
export const H6 = ({ children }) => (
<h6 className="tw-text-base tw-py-1 tw-font-medium tw-italic tw-m-0 tw-tracking-tight lg:tw-text-lg">
<h6 className="tw:text-base tw:py-1 tw:font-medium tw:italic tw:m-0 tw:tracking-tight tw:lg:text-lg">
{children}
</h6>
)

View file

@ -33,18 +33,18 @@ export const Highlight = ({
}
const preProps = {
className: `language-${language} hljs tw-text-base lg:tw-text-lg tw-whitespace-break-spaces tw-overflow-scroll tw-pr-4`,
className: `language-${language} hljs tw:text-base tw:lg:text-lg tw:whitespace-break-spaces tw:overflow-scroll tw:pr-4`,
}
if (raw) preProps.dangerouslySetInnerHTML = { __html: raw }
const label = title ? title : defaultTitles[language] ? defaultTitles[language] : language
return (
<div className="hljs tw-my-4">
<div className="hljs tw:my-4">
<div
className={`
tw-flex tw-flex-row tw-justify-between tw-items-center tw-text-xs tw-font-medium tw-text-warning
tw-mt-1 tw-border-b tw-border-neutral-content tw-border-opacity-25 tw-px-4 tw-py-1 tw-mb-2 lg:tw-text-sm
tw:flex tw:flex-row tw:justify-between tw:items-center tw:text-xs tw:font-medium tw:text-warning
tw:mt-1 tw:border-b tw:border-neutral-content tw:border-opacity-25 tw:px-4 tw:py-1 tw:mb-2 tw:lg:text-sm
`}
>
<span>{label}</span>

View file

@ -9,7 +9,7 @@ const page =
* Used inside the pattern editor
*/
export const IconWrapper = ({
className = 'tw-w-6 tw-h-6',
className = 'tw:w-6 tw:h-6',
stroke = 2,
children = null,
fill = false,
@ -60,19 +60,19 @@ export const BeakerIcon = (props) => (
// Looks like a left U-turn that we slightly rotate
export const BackIcon = (props) => (
<IconWrapper {...props} className={`${props.className || 'tw-w-6 tw-h-6'} tw--rotate-45`}>
<IconWrapper {...props} className={`${props.className || 'tw:w-6 tw:h-6'} tw:-rotate-45`}>
<path d="M9 15 3 9m0 0 6-6M3 9h12a6 6 0 0 1 0 12h-3" />
</IconWrapper>
)
// Looks like a red X
export const BoolNoIcon = ({ size = 6 }) => (
<NoIcon className={`tw-w-${size} tw-h-${size} tw-text-error`} stroke={4} />
<NoIcon className={`tw:w-${size} tw:h-${size} tw:text-error`} stroke={4} />
)
// Looks like a green checkbox
export const BoolYesIcon = ({ size = 6 }) => (
<OkIcon className={`tw-w-${size} tw-h-${size} tw-text-success`} stroke={4} />
<OkIcon className={`tw:w-${size} tw:h-${size} tw:text-success`} stroke={4} />
)
// Looks like a bookmark
@ -258,7 +258,7 @@ export const ExportIcon = (props) => (
// Looks like a ! in a triangle, is intended to be shown on an error background
export const FailureIcon = ({ size = 6 }) => (
<NoIcon className={`tw-w-${size} tw-h-${size} tw-text-secondary-content`} stroke={4} />
<NoIcon className={`tw:w-${size} tw:h-${size} tw:text-secondary-content`} stroke={4} />
)
// Looks like a funnel
@ -682,10 +682,10 @@ export const SignoutIcon = (props) => (
export const SpinnerIcon = (props) => (
<IconWrapper
{...props}
className={`${props.className ? props.className : 'tw-h-6 tw-w-6'} tw-animate-spin`}
className={`${props.className ? props.className : 'tw:h-6 tw:w-6'} tw:animate-spin`}
>
<circle
className="tw-opacity-25"
className="tw:opacity-25"
cx="12"
cy="12"
r="10"
@ -693,7 +693,7 @@ export const SpinnerIcon = (props) => (
strokeWidth="4"
></circle>
<path
className="tw-opacity-85"
className="tw:opacity-85"
fill="currentColor"
stroke="none"
d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"
@ -703,7 +703,7 @@ export const SpinnerIcon = (props) => (
// Looks like a white checkbox, intended to be shown on a success-colored background
export const SuccessIcon = ({ size = 6 }) => (
<OkIcon className={`tw-w-${size} tw-h-${size} tw-text-secondary-content`} stroke={4} />
<OkIcon className={`tw:w-${size} tw:h-${size} tw:text-secondary-content`} stroke={4} />
)
// Looks like the TikTok t

View file

@ -32,8 +32,8 @@ export const _Tab = ({
setActiveTab, // Method to set the active tab
}) => (
<button
className={`tw-text-lg tw-font-bold tw-capitalize tw-daisy-tab tw-daisy-tab-bordered tw-grow
${activeTab === id ? 'tw-daisy-tab-active' : ''}`}
className={`tw:text-lg tw:font-bold tw:capitalize tw:daisy-tab tw:daisy-tab-bordered tw:grow
${activeTab === id ? 'tw:daisy-tab-active' : ''}`}
onClick={() => setActiveTab(id)}
>
{label ? label : id}
@ -52,14 +52,14 @@ const HelpLink = ({ help, Link = false }) => {
if (typeof help === 'function')
return (
<button onClick={() => help} title="Show help">
<HelpIcon className="tw-w-5 tw-h-5" />
<HelpIcon className="tw:w-5 tw:h-5" />
</button>
)
if (typeof help === 'string')
return (
<Link href={help} target="_BLANK" rel="nofollow" title="Show help">
<HelpIcon className="tw-w-5 tw-h-5" />
<HelpIcon className="tw:w-5 tw:h-5" />
</Link>
)
@ -84,7 +84,7 @@ export const FormControl = ({
const topLabelChildren = (
<>
{label ? (
<span className="tw-daisy-label-text tw-text-sm lg:tw-text-base tw-font-bold tw-mb-1 tw-text-inherit tw-inline-flex tw-items-center tw-gap-1">
<span className="tw:daisy-label-text tw:text-sm tw:lg:text-base tw:font-bold tw:mb-1 tw:text-inherit tw:inline-flex tw:items-center tw:gap-1">
{label} <HelpLink {...{ help, Link }} />
</span>
) : (
@ -92,33 +92,33 @@ export const FormControl = ({
<HelpLink {...{ help, Link }} />
</span>
)}
{labelTR ? <span className="tw-daisy-label-text-alt tw--mb-1">{labelTR}</span> : null}
{labelTR ? <span className="tw:daisy-label-text-alt tw:-mb-1">{labelTR}</span> : null}
</>
)
const bottomLabelChildren = (
<>
{labelBL ? <span className="tw-daisy-label-text-alt">{labelBL}</span> : null}
{labelBR ? <span className="tw-daisy-label-text-alt">{labelBR}</span> : null}
{labelBL ? <span className="tw:daisy-label-text-alt">{labelBL}</span> : null}
{labelBR ? <span className="tw:daisy-label-text-alt">{labelBR}</span> : null}
</>
)
return (
<div className="tw-daisy-form-control tw-w-full tw-mt-2">
<div className="tw:daisy-form-control tw:w-full tw:mt-2">
{forId ? (
<label className="tw-daisy-label tw-pb-0" htmlFor={forId}>
<label className="tw:daisy-label tw:pb-0" htmlFor={forId}>
{topLabelChildren}
</label>
) : label ? (
<div className="tw-daisy-label tw-pb-0">{topLabelChildren}</div>
<div className="tw:daisy-label tw:pb-0">{topLabelChildren}</div>
) : null}
{children}
{labelBL || labelBR ? (
forId ? (
<label className="tw-daisy-label" htmlFor={forId}>
<label className="tw:daisy-label" htmlFor={forId}>
{bottomLabelChildren}
</label>
) : (
<div className="tw-daisy-label">{bottomLabelChildren}</div>
<div className="tw:daisy-label">{bottomLabelChildren}</div>
)
) : null}
</div>
@ -137,13 +137,13 @@ export const ButtonFrame = ({
}) => (
<button
className={`
tw-daisy-btn tw-daisy-btn-ghost tw-daisy-btn-secondary tw-h-fit
tw-w-full ${dense ? 'tw-mt-1 tw-daisy-btn-sm tw-font-light' : 'tw-mt-2 tw-py-4 tw-h-auto tw-content-start'}
tw-border-2 tw-border-secondary tw-text-left tw-bg-opacity-20
${accordion ? 'hover:tw-bg-transparent' : 'hover:tw-bg-secondary hover:tw-bg-opacity-10'}
hover:tw-border-secondary hover:tw-border-solid hover:tw-border-2
${active ? 'tw-border-solid' : 'tw-border-dotted'}
${active && !accordion ? 'tw-bg-secondary' : 'tw-bg-transparent'}
tw:daisy-btn tw:daisy-btn-ghost tw:daisy-btn-secondary tw:h-fit
tw:w-full ${dense ? 'tw:mt-1 tw:daisy-btn-sm tw:font-light' : 'tw:mt-2 tw:py-4 tw:h-auto tw:content-start'}
tw:border-2 tw:border-secondary tw:text-left tw:bg-secondary/20
${accordion ? 'tw:hover:bg-transparent' : 'tw:hover:bg-secondary/10'}
tw:hover:border-secondary tw:hover:border-solid tw:hover:border-2
${active ? 'tw:border-solid' : 'tw:border-dotted'}
${active && !accordion ? 'tw:bg-secondary' : 'tw:bg-transparent'}
`}
onClick={onClick}
>
@ -176,12 +176,12 @@ export const NumberInput = ({
placeholder={placeholder}
value={current}
onChange={(evt) => update(evt.target.value)}
className={`tw-daisy-input tw-w-full tw-daisy-input-bordered ${
className={`tw:daisy-input tw:w-full tw:daisy-input-bordered ${
current === original
? 'tw-daisy-input-secondary'
? 'tw:daisy-input-secondary'
: valid(current)
? 'tw-daisy-input-success'
: 'tw-daisy-input-error'
? 'tw:daisy-input-success'
: 'tw:daisy-input-error'
}`}
{...{ max, min, step }}
/>
@ -209,12 +209,12 @@ export const StringInput = ({
placeholder={placeholder}
value={current}
onChange={(evt) => update(evt.target.value)}
className={`tw-daisy-input tw-w-full tw-daisy-input-bordered tw-text-current ${
className={`tw:daisy-input tw:w-full tw:daisy-input-bordered tw:text-current ${
current === original
? 'tw-daisy-input-secondary'
? 'tw:daisy-input-secondary'
: valid(current)
? 'tw-daisy-input-success'
: 'tw-daisy-input-error'
? 'tw:daisy-input-success'
: 'tw:daisy-input-error'
}`}
/>
</FormControl>
@ -260,7 +260,7 @@ export const PasswordInput = ({
forId={id}
labelBR={
<button
className="tw-btn tw-btn-primary tw-btn-ghost tw-btn-xs tw--mt-2"
className="tw:btn tw:btn-primary tw:btn-ghost tw:btn-xs tw:-mt-2"
onClick={() => setReveal(!reveal)}
>
{reveal ? 'Hide Password' : 'Reveal Password'}
@ -273,7 +273,7 @@ export const PasswordInput = ({
placeholder={placeholder}
value={current}
onChange={(evt) => update(evt.target.value)}
className={`tw-daisy-input tw-w-full tw-daisy-input-bordered ${
className={`tw:daisy-input tw:w-full tw:daisy-input-bordered ${
valid(current) ? 'input-success' : 'input-error'
}`}
{...extraProps}
@ -304,12 +304,12 @@ export const EmailInput = ({
placeholder={placeholder}
value={current}
onChange={(evt) => update(evt.target.value)}
className={`tw-daisy-input tw-w-full tw-daisy-input-bordered ${
className={`tw:daisy-input tw:w-full tw:daisy-input-bordered ${
current === original
? 'tw-daisy-input-secondary'
? 'tw:daisy-input-secondary'
: valid(current)
? 'tw-daisy-input-success'
: 'tw-daisy-input-error'
? 'tw:daisy-input-success'
: 'tw:daisy-input-error'
}`}
/>
</FormControl>
@ -329,7 +329,7 @@ export const DesignInput = ({
<FormControl label={label} forId={id}>
<select
id={id}
className="tw-daisy-select tw-daisy-select-bordered tw-w-full"
className="tw:daisy-select tw:daisy-select-bordered tw:w-full"
onChange={(evt) => update(evt.target.value)}
value={current}
>
@ -398,7 +398,7 @@ export const ImageInput = ({
return (
<FormControl label={label}>
<div
className="tw-bg-base-100 tw-w-full tw-h-36 tw-mb-2 tw-mx-auto tw-flex tw-flex-col tw-items-center tw-text-center tw-justify-center"
className="tw:bg-base-100 tw:w-full tw:h-36 tw:mb-2 tw:mx-auto tw:flex tw:flex-col tw:items-center tw:text-center tw:justify-center"
style={{
backgroundImage: `url(${
uploadedId ? cloudflareImageUrl({ type: 'public', id: uploadedId }) : current
@ -409,7 +409,7 @@ export const ImageInput = ({
}}
>
<button
className="tw-daisy-btn tw-daisy-btn-neutral tw-daisy-btn-circle tw-opacity-50 hover:tw-opacity-100"
className="tw:daisy-btn tw:daisy-btn-neutral tw:daisy-btn-circle tw:opacity-50 tw:hover:opacity-100"
onClick={() => update(original)}
>
<ResetIcon />
@ -423,32 +423,32 @@ export const ImageInput = ({
<div
{...getRootProps()}
className={`
tw-flex tw-rounded-lg tw-w-full tw-flex-col tw-items-center tw-justify-center
lg:tw-p-6 lg:tw-border-4 lg:tw-border-secondary lg:tw-border-dashed
tw:flex tw:rounded-lg tw:w-full tw:flex-col tw:items-center tw:justify-center
tw:lg:p-6 tw:lg:border-4 tw:lg:border-secondary tw:lg:border-dashed
`}
>
<input {...getInputProps()} />
<p className="tw-hidden lg:tw-block tw-p-0 tw-m-0">Drag and drop and image here</p>
<p className="tw-hidden lg:tw-block tw-p-0 tw-my-2">or</p>
<p className="tw:hidden tw:lg:block tw:p-0 tw:m-0">Drag and drop and image here</p>
<p className="tw:hidden tw:lg:block tw:p-0 tw:my-2">or</p>
<button
className={`tw-daisy-btn tw-daisy-btn-secondary tw-daisy-btn-outline tw-mt-4 tw-px-8`}
className={`tw:daisy-btn tw:daisy-btn-secondary tw:daisy-btn-outline tw:mt-4 tw:px-8`}
>
Select an image to use
</button>
</div>
<p className="tw-p-0 tw-my-2 tw-text-center">or</p>
<div className="tw-flex tw-flex-row tw-items-center">
<p className="tw:p-0 tw:my-2 tw:text-center">or</p>
<div className="tw:flex tw:flex-row tw:items-center">
<input
id={id}
type="url"
className="tw-daisy-input tw-daisy-input-secondary tw-w-full tw-daisy-input-bordered"
className="tw:daisy-input tw:daisy-input-secondary tw:w-full tw:daisy-input-bordered"
placeholder="Paste an image URL here"
value={current}
onChange={active ? (evt) => setUrl(evt.target.value) : (evt) => update(evt.target.value)}
/>
{active && (
<button
className="tw-daisy-btn tw-daisy-btn-secondary tw-ml-2 tw-capitalize"
className="tw:daisy-btn tw:daisy-btn-secondary tw:ml-2 tw:capitalize"
disabled={!url || url.length < 1}
onClick={() => upload(url, true)}
>
@ -482,10 +482,10 @@ export const ListInput = ({
<FormControl label={label}>
{list.map((item, i) => (
<ButtonFrame key={i} active={item.val === current} onClick={() => update(item.val)}>
<div className="tw-w-full tw-flex tw-flex-col tw-gap-2">
<div className="tw-w-full tw-text-lg tw-leading-5">{item.label}</div>
<div className="tw:w-full tw:flex tw:flex-col tw:gap-2">
<div className="tw:w-full tw:text-lg tw:leading-5">{item.label}</div>
{item.desc ? (
<div className="tw-w-full tw-text-normal tw-font-normal tw-normal-case tw-pt-1 tw-leading-5">
<div className="tw:w-full tw:text-normal tw:font-normal tw:normal-case tw:pt-1 tw:leading-5">
{item.desc}
</div>
) : null}
@ -514,11 +514,11 @@ export const MarkdownInput = ({
>
<Tabs tabs={['edit', 'preview']}>
<Tab key="edit">
<div className="tw-flex tw-flex-row tw-items-center tw-mt-2">
<div className="tw:flex tw:flex-row tw:items-center tw:mt-2">
<textarea
id={id}
rows="5"
className="tw-daisy-textarea tw-daisy-textarea-bordered tw-daisy-textarea-lg tw-w-full"
className="tw:daisy-textarea tw:daisy-textarea-bordered tw:daisy-textarea-lg tw:w-full"
value={current}
placeholder={placeholder}
onChange={(evt) => update(evt.target.value)}
@ -580,15 +580,15 @@ export const MeasurementInput = ({
let inputClasses = 'daisy-input-secondary'
let bottomLeftLabel = null
if (valid === true) {
inputClasses = 'daisy-input-success tw-outline-success'
inputClasses = 'daisy-input-success tw:outline-success'
const val = `${validatedVal}${isDegree ? '°' : imperial ? '"' : 'cm'}`
bottomLeftLabel = (
<span className="tw-font-medium tw-text-base tw-text-success tw--mt-2 tw-block">{val}</span>
<span className="tw:font-medium tw:text-base tw:text-success tw:-mt-2 tw:block">{val}</span>
)
} else if (valid === false) {
inputClasses = 'daisy-input-error'
bottomLeftLabel = (
<span className="tw-font-medium tw-text-error tw-text-base tw--mt-2 tw-block">
<span className="tw:font-medium tw:text-error tw:text-base tw:-mt-2 tw:block">
¯\_()_/¯
</span>
)
@ -609,7 +609,7 @@ export const MeasurementInput = ({
labelBL={bottomLeftLabel}
>
<label
className={`tw-daisy-input tw-daisy-input-bordered tw-flex tw-items-center tw-gap-2 tw-border ${inputClasses} tw-mb-1 tw-outline tw-outline-base-300 tw-bg-transparent tw-outline-2 tw-outline-offset-2`}
className={`tw:daisy-input tw:daisy-input-bordered tw:flex tw:items-center tw:gap-2 tw:border ${inputClasses} tw:mb-1 tw:outline tw:outline-base-300 tw:bg-transparent tw:outline-2 tw:outline-offset-2`}
>
<input
id={id}
@ -619,12 +619,12 @@ export const MeasurementInput = ({
placeholder={placeholder}
value={localVal}
onChange={(evt) => localUpdate(evt.target.value)}
className={`tw-border-0 tw-grow-2 tw-w-full`}
className={`tw:border-0 tw:grow-2 tw:w-full`}
/>
{isDegree ? '°' : imperial ? 'inch' : 'cm'}
<label>
<button className="tw-text-warning hover:tw-text-error" onClick={clearValue}>
<TrashIcon className="tw-w-5 tw-h-5 tw--mb-1" />
<button className="tw:text-warning tw:hover:text-error" onClick={clearValue}>
<TrashIcon className="tw:w-5 tw:h-5 tw:-mb-1" />
</button>
</label>
</label>
@ -664,9 +664,9 @@ export const FileInput = ({
if (current)
return (
<FormControl label={label} isValid={valid(current)}>
<div className="tw-bg-base-100 tw-w-full tw-h-36 tw-mb-2 tw-mx-auto tw-flex tw-flex-col tw-items-center tw-text-center tw-justify-center">
<div className="tw:bg-base-100 tw:w-full tw:h-36 tw:mb-2 tw:mx-auto tw:flex tw:flex-col tw:items-center tw:text-center tw:justify-center">
<button
className="tw-daisy-btn tw-daisy-btn-neutral tw-daisy-btn-circle tw-opacity-50 hover:tw-opacity-100"
className="tw:daisy-btn tw:daisy-btn-neutral tw:daisy-btn-circle tw:opacity-50 tw:hover:opacity-100"
onClick={() => update(original)}
>
<ResetIcon />
@ -683,14 +683,14 @@ export const FileInput = ({
<div
{...getRootProps()}
className={`
tw-flex tw-rounded-lg tw-w-full tw-flex-col tw-items-center tw-justify-center
sm:tw-p-6 sm:tw-border-4 sm:tw-border-secondary sm:tw-border-dashed
tw:flex tw:rounded-lg tw:w-full tw:flex-col tw:items-center tw:justify-center
tw:sm:p-6 tw:sm:border-4 tw:sm:border-secondary tw:sm:border-dashed
`}
>
<input {...getInputProps()} />
<p className="tw-hidden lg:tw-block tw-p-0 tw-m-0">Drag and drop your file here</p>
<p className="tw:hidden tw:lg:block tw:p-0 tw:m-0">Drag and drop your file here</p>
<button
className={`tw-daisy-btn tw-daisy-btn-secondary tw-daisy-btn-outline tw-mt-4 tw-px-8`}
className={`tw:daisy-btn tw:daisy-btn-secondary tw:daisy-btn-outline tw:mt-4 tw:px-8`}
>
Browse...
</button>
@ -730,7 +730,7 @@ export const ToggleInput = ({
type="checkbox"
value={current}
onChange={() => update(list.indexOf(current) === 0 ? list[1] : list[0])}
className="tw-daisy-toggle tw-my-3 tw-daisy-toggle-primary"
className="tw:daisy-toggle tw:my-3 tw:daisy-toggle-primary"
checked={list.indexOf(current) === 0 ? true : false}
/>
</FormControl>

View file

@ -34,12 +34,12 @@ export const KeyVal = ({
const inner = (
<>
<span
className={`${sharedClasses} ${small ? 'tw-rounded-l' : 'tw-rounded-l-lg'} ${colorClasses1} ${small ? 'tw-text-xs' : ''} tw-pr-0.5`}
className={`${sharedClasses} ${small ? 'tw:rounded-l' : 'tw:rounded-l-lg'} ${colorClasses1} ${small ? 'tw:text-xs' : ''} tw:pr-0.5`}
>
{k}
</span>
<span
className={`${sharedClasses} ${small ? 'tw-rounded-r' : 'tw-rounded-r-lg'} ${colorClasses2} ${small ? 'tw-text-xs' : ''} tw-pl-0.5`}
className={`${sharedClasses} ${small ? 'tw:rounded-r' : 'tw:rounded-r-lg'} ${colorClasses2} ${small ? 'tw:text-xs' : ''} tw:pl-0.5`}
>
{val}
</span>
@ -48,7 +48,7 @@ export const KeyVal = ({
return onClick === false ? (
<button
className="tw-daisy-btn-ghost tw-p-0"
className="tw:daisy-btn-ghost tw:p-0"
onClick={() => {
copyToClipboard(val)
handleCopied(setCopied, setLoadingStatus, k)
@ -58,7 +58,7 @@ export const KeyVal = ({
</button>
) : (
<button
className="tw-daisy-btn-ghost tw-p-0"
className="tw:daisy-btn-ghost tw:p-0"
onClick={typeof onClick === 'function' ? onClick : null}
>
{inner}
@ -79,19 +79,19 @@ const LinkKeyVal = ({
const inner = (
<>
<span
className={`${sharedClasses} ${small ? 'tw-rounded-l' : 'tw-rounded-l-lg'} ${colorClasses1} ${small ? 'tw-text-xs' : ''} tw-pr-0.5`}
className={`${sharedClasses} ${small ? 'tw:rounded-l' : 'tw:rounded-l-lg'} ${colorClasses1} ${small ? 'tw:text-xs' : ''} tw:pr-0.5`}
>
{k}
</span>
<span
className={`${sharedClasses} ${small ? 'tw-rounded-r' : 'tw-rounded-r-lg'} ${colorClasses2} ${small ? 'tw-text-xs' : ''} tw-pl-0.5`}
className={`${sharedClasses} ${small ? 'tw:rounded-r' : 'tw:rounded-r-lg'} ${colorClasses2} ${small ? 'tw:text-xs' : ''} tw:pl-0.5`}
>
{val}
</span>
</>
)
const linkProps = {
className: 'tw-daisy-btn-ghost tw-p-0 hover:tw-no-underline hover:tw-bg-transparent',
className: 'tw:daisy-btn-ghost tw:p-0 tw:hover:no-underline tw:hover:bg-transparent',
href: href,
}
@ -102,33 +102,33 @@ const LinkKeyVal = ({
* If we configure the tailwind classes dynamically, they won't be picked up
* So let's create a component for each color
*/
const sharedClasses = `tw-px-1 tw-text-sm tw-font-medium tw-whitespace-nowrap tw-border-2 tw-border-solid`
const primaryClasses1 = `tw-text-primary-content tw-bg-primary tw-border-primary`
const primaryClasses2 = `tw-text-primary tw-border-primary`
const secondaryClasses1 = `tw-text-secondary-content tw-bg-secondary tw-border-secondary`
const secondaryClasses2 = `tw-text-secondary tw-border-secondary`
const neutralClasses1 = `tw-text-neutral-content tw-bg-neutral tw-border-neutral`
const neutralClasses2 = `tw-text-neutral tw-border-neutral`
const accentClasses1 = `tw-text-accent-content tw-bg-accent tw-border-accent`
const accentClasses2 = `tw-text-accent tw-border-accent`
const infoClasses1 = `tw-text-info-content tw-bg-info tw-border-info`
const infoClasses2 = `tw-text-info tw-border-info`
const warningClasses1 = `tw-text-warning-content tw-bg-warning tw-border-warning`
const warningClasses2 = `tw-text-warning tw-border-warning`
const successClasses1 = `tw-text-warning-content tw-bg-success tw-border-success`
const successClasses2 = `tw-text-success tw-border-success`
const errorClasses1 = `tw-text-error-content tw-bg-error tw-border-error`
const errorClasses2 = `tw-text-error tw-border-error`
const sharedClasses = `tw:px-1 tw:text-sm tw:font-medium tw:whitespace-nowrap tw:border-2 tw:border-solid`
const primaryClasses1 = `tw:text-primary-content tw:bg-primary tw:border-primary`
const primaryClasses2 = `tw:text-primary tw:border-primary`
const secondaryClasses1 = `tw:text-secondary-content tw:bg-secondary tw:border-secondary`
const secondaryClasses2 = `tw:text-secondary tw:border-secondary`
const neutralClasses1 = `tw:text-neutral-content tw:bg-neutral tw:border-neutral`
const neutralClasses2 = `tw:text-neutral tw:border-neutral`
const accentClasses1 = `tw:text-accent-content tw:bg-accent tw:border-accent`
const accentClasses2 = `tw:text-accent tw:border-accent`
const infoClasses1 = `tw:text-info-content tw:bg-info tw:border-info`
const infoClasses2 = `tw:text-info tw:border-info`
const warningClasses1 = `tw:text-warning-content tw:bg-warning tw:border-warning`
const warningClasses2 = `tw:text-warning tw:border-warning`
const successClasses1 = `tw:text-warning-content tw:bg-success tw:border-success`
const successClasses2 = `tw:text-success tw:border-success`
const errorClasses1 = `tw:text-error-content tw:bg-error tw:border-error`
const errorClasses2 = `tw:text-error tw:border-error`
const PrimarySpans = ({ small, k, val }) => (
<>
<span
className={`${sharedClasses} ${small ? 'tw-rounded-l' : 'tw-rounded-l-lg'} ${primaryClasses} ${small ? 'tw-text-xs' : ''}`}
className={`${sharedClasses} ${small ? 'tw:rounded-l' : 'tw:rounded-l-lg'} ${primaryClasses} ${small ? 'tw:text-xs' : ''}`}
>
{k}
</span>
<span
className={`${sharedClasses} ${small ? 'tw-rounded-r' : 'tw-rounded-r-lg'} ${primaryClasses} ${small ? 'tw-text-xs' : ''}`}
className={`${sharedClasses} ${small ? 'tw:rounded-r' : 'tw:rounded-r-lg'} ${primaryClasses} ${small ? 'tw:text-xs' : ''}`}
>
{val}
</span>

View file

@ -17,10 +17,10 @@ export const Layout = ({ children = [], crumbs = [], description, Link = false,
return (
<BaseLayout>
<div className="tw-max-w-xl tw-w-full tw-mx-auto">
<div className="tw:max-w-xl tw:w-full tw:mx-auto">
<Breadcrumbs {...{ crumbs, title, Link }} />
<h1 className="tw-break-words">{title}</h1>
<div className="xl:tw-pl-4">{children}</div>
<h1 className="tw:break-words">{title}</h1>
<div className="tw:xl:pl-4">{children}</div>
</div>
</BaseLayout>
)
@ -33,7 +33,7 @@ export const Layout = ({ children = [], crumbs = [], description, Link = false,
* @param {array} props.children - The content to go in the layout
*/
export const BaseLayout = ({ children }) => (
<div className="tw-flex tw-flex-row tw-items-start tw-w-full tw-justify-between 2xl:tw-px-36 xl:tw-px-12 tw-px-4 tw-gap-0 lg:tw-gap-4 xl:tw-gap-8 3xl:tw-gap-12">
<div className="tw:flex tw:flex-row tw:items-start tw:w-full tw:justify-between tw:2xl:px-36 tw:xl:px-12 tw:px-4 tw:gap-0 tw:lg:gap-4 tw:xl:gap-8 3xl:tw:gap-12">
{children}
</div>
)
@ -45,7 +45,7 @@ export const BaseLayout = ({ children }) => (
* @param {array} props.children - The content to go in the layout
*/
export const BaseLayoutLeft = ({ children = [] }) => (
<div className="tw-max-w-96 tw-w-1/4 tw-hidden lg:tw-block tw-shrink-0 tw-my-8 tw-sticky tw-top-4 tw-max-h-screen tw-overflow-scroll">
<div className="tw:max-w-96 tw:w-1/4 tw:hidden tw:lg:block tw:shrink-0 tw:my-8 tw:sticky tw:top-4 tw:max-h-screen tw:overflow-scroll">
{children}
</div>
)
@ -57,7 +57,7 @@ export const BaseLayoutLeft = ({ children = [] }) => (
* @param {array} props.children - The content to go in the layout
*/
export const BaseLayoutRight = ({ children = [] }) => (
<div className="tw-max-w-96 tw-w-1/4 tw-hidden xl:tw-block tw-my-8 tw-sticky tw-top-2">
<div className="tw:max-w-96 tw:w-1/4 tw:hidden tw:xl:block tw:my-8 tw:sticky tw:top-2">
{children}
</div>
)
@ -70,7 +70,7 @@ export const BaseLayoutRight = ({ children = [] }) => (
* @param {array} props.wide - Whether or not to use the wide view
*/
export const BaseLayoutProse = ({ children = [], wide = false }) => (
<div className={`tw-grow tw-w-full tw-m-auto tw-max-w-${wide ? 'full' : 'prose'} tw-my-8`}>
<div className={`tw:grow tw:w-full tw:m-auto tw:max-w-${wide ? 'full' : 'prose'} tw:my-8`}>
{children}
</div>
)
@ -82,7 +82,7 @@ export const BaseLayoutProse = ({ children = [], wide = false }) => (
* @param {array} props.children - The content to go in the layout
*/
export const BaseLayoutWide = ({ children = [] }) => (
<div className="tw-grow tw-w-full tw-m-auto tw-my-8 tw-grow">{children}</div>
<div className="tw:grow tw:w-full tw:m-auto tw:my-8 tw:grow">{children}</div>
)
/*
@ -94,7 +94,7 @@ export const BaseLayoutWide = ({ children = [] }) => (
export const NoTitleLayout = ({ children }) => {
return (
<BaseLayout>
<div className="tw-max-w-xl tw-w-full tw-mx-auto">
<div className="tw:max-w-xl tw:w-full tw:mx-auto">
<div>{children}</div>
</div>
</BaseLayout>

View file

@ -38,7 +38,7 @@ export const BellaFront = ({ className, stroke = 1 }) => (
* React component for the back
*/
export const BellaBack = ({
className = 'tw-w-full', // CSS classes to apply
className = 'tw:w-full', // CSS classes to apply
stroke = 1, // Stroke width to use
}) => {
// Normalize stroke across designs

View file

@ -38,7 +38,7 @@ export const BentFront = ({ className, stroke = 1 }) => (
* React component for the back
*/
export const BentBack = ({
className = 'tw-w-full', // CSS classes to apply
className = 'tw:w-full', // CSS classes to apply
stroke = 1, // Stroke width to use
}) => {
// Normalize stroke across designs

View file

@ -38,7 +38,7 @@ export const BibiFront = ({ className, stroke = 1 }) => (
* React component for the back
*/
export const BibiBack = ({
className = 'tw-w-full', // CSS classes to apply
className = 'tw:w-full', // CSS classes to apply
stroke = 1, // Stroke width to use
}) => {
// Normalize stroke across designs

View file

@ -38,7 +38,7 @@ export const BobFront = ({ className, stroke = 1 }) => (
* React component for the back
*/
export const BobBack = ({
className = 'tw-w-full', // CSS classes to apply
className = 'tw:w-full', // CSS classes to apply
stroke = 1, // Stroke width to use
}) => {
// Normalize stroke across designs

View file

@ -40,7 +40,7 @@ export const BreannaFront = ({ className, stroke = 1 }) => (
* React component for the back
*/
export const BreannaBack = ({
className = 'tw-w-full', // CSS classes to apply
className = 'tw:w-full', // CSS classes to apply
stroke = 1, // Stroke width to use
}) => {
// Normalize stroke across designs

View file

@ -38,7 +38,7 @@ export const BrianFront = ({ className, stroke = 1 }) => (
* React component for the back
*/
export const BrianBack = ({
className = 'tw-w-full', // CSS classes to apply
className = 'tw:w-full', // CSS classes to apply
stroke = 1, // Stroke width to use
}) => {
// Normalize stroke across designs

View file

@ -40,7 +40,7 @@ export const BruceFront = ({ className, stroke = 1 }) => (
* React component for the back
*/
export const BruceBack = ({
className = 'tw-w-full', // CSS classes to apply
className = 'tw:w-full', // CSS classes to apply
stroke = 1, // Stroke width to use
}) => {
// Normalize stroke across designs

View file

@ -9,7 +9,7 @@ import React from 'react'
* @return LineDrawing as JSX
*/
export const LineDrawingWrapper = ({
className = 'tw-w-full', // CSS classes to apply
className = 'tw:w-full', // CSS classes to apply
viewBox = '0 0 100 100', // SVG viewBox
stroke = 1, // Stroke to use
children = [], // The actual linedrawing

View file

@ -54,7 +54,7 @@ export const SuccessLink = ({
href,
title = false,
children,
className = `${linkClasses} tw-text-success-content hover:tw-text-success-content`,
className = `${linkClasses} tw:text-success-content tw:hover:text-success-content`,
style = {},
}) => (
<a href={href} className={className} title={title ? title : ''} style={style}>
@ -68,22 +68,22 @@ export const CardLink = ({
icon,
children,
Link,
className = 'tw-bg-base-200 tw-text-base-content',
className = 'tw:bg-base-200 tw:text-base-content',
}) => {
if (!Link) Link = BaseLink
return (
<Link
href={href}
className={`tw-px-8 tw-py-10 tw-rounded-lg tw-block ${className}
hover:tw-bg-secondary hover:tw-bg-opacity-10 tw-shadow-lg
tw-transition-color tw-duration-300 grow hover:tw-no-underline hover:tw-text-base-content`}
className={`tw:px-8 tw:py-10 tw:rounded-lg tw:block ${className}
tw:hover:bg-secondary/5 tw:shadow-lg tw:bg-base-200
tw:transition-color tw:duration-300 grow tw:hover:no-underline no-hover-decoration`}
>
<h2 className="tw-mb-4 tw-text-inherit tw-flex tw-flex-row tw-gap-4 tw-justify-between tw-items-center">
{title}
<span className="tw-shrink-0">{icon}</span>
<h2 className="tw:mb-4 tw:text-base-content tw:flex tw:flex-row tw:gap-4 tw:justify-between tw:items-center">
<span className="tw:text-base-content">{title}</span>
<span className="tw:shrink-0 tw:text-base-content">{icon}</span>
</h2>
{children}
<div className="tw:text-base-content">{children}</div>
</Link>
)
}

View file

@ -2,33 +2,33 @@ import React from 'react'
import { TipIcon, ChatIcon, WarningIcon } from '@freesewing/react/components/Icon'
export const MiniTip = ({ children }) => (
<div className="tw-flex tw-flex-row tw-border tw-border-success tw-rounded">
<div className="tw-bg-success tw-text-success-content tw-p-1 tw-rounded-l tw-flex tw-flex-row tw-items-center">
<TipIcon className="tw-w-6 tw-h-6 tw-text-success-content" />
<div className="tw:flex tw:flex-row tw:border tw:border-success tw:rounded">
<div className="tw:bg-success tw:text-success-content tw:p-1 tw:rounded-l tw:flex tw:flex-row tw:items-center">
<TipIcon className="tw:w-6 tw:h-6 tw:text-success-content" />
</div>
<div className="tw-p-1 tw-px-2 tw-text-sm tw-font-medium tw-bg-success/10 tw-grow tw-rounded-r">
<div className="tw:p-1 tw:px-2 tw:text-sm tw:font-medium tw:bg-success/10 tw:grow tw:rounded-r">
{children}
</div>
</div>
)
export const MiniNote = ({ children }) => (
<div className="tw-flex tw-flex-row tw-border tw-border-info tw-rounded">
<div className="tw-bg-info tw-text-info-content tw-p-1 tw-rounded-l tw-flex tw-flex-row tw-items-center">
<ChatIcon className="tw-w-6 tw-h-6 tw-text-info-content" />
<div className="tw:flex tw:flex-row tw:border tw:border-info tw:rounded">
<div className="tw:bg-info tw:text-info-content tw:p-1 tw:rounded-l tw:flex tw:flex-row tw:items-center">
<ChatIcon className="tw:w-6 tw:h-6 tw:text-info-content" />
</div>
<div className="tw-p-1 tw-px-2 tw-text-sm tw-font-medium tw-bg-info/10 tw-grow tw-rounded-r">
<div className="tw:p-1 tw:px-2 tw:text-sm tw:font-medium tw:bg-info/10 tw:grow tw:rounded-r">
{children}
</div>
</div>
)
export const MiniWarning = ({ children }) => (
<div className="tw-flex tw-flex-row tw-border tw-border-warning tw-rounded">
<div className="tw-bg-warning tw-text-warning-content tw-p-1 tw-rounded-l tw-flex tw-flex-row tw-items-center">
<WarningIcon className="tw-w-6 tw-h-6 tw-text-warning-content" />
<div className="tw:flex tw:flex-row tw:border tw:border-warning tw:rounded">
<div className="tw:bg-warning tw:text-warning-content tw:p-1 tw:rounded-l tw:flex tw:flex-row tw:items-center">
<WarningIcon className="tw:w-6 tw:h-6 tw:text-warning-content" />
</div>
<div className="tw-p-1 tw-px-2 tw-text-sm tw-font-medium tw-bg-warning/10 tw-grow tw-rounded-r">
<div className="tw:p-1 tw:px-2 tw:text-sm tw:font-medium tw:bg-warning/10 tw:grow tw:rounded-r">
{children}
</div>
</div>

View file

@ -3,10 +3,10 @@ import { ModalContext } from '@freesewing/react/context/Modal'
import { CloseIcon } from '@freesewing/react/components/Icon'
const slideClasses = {
left: 'tw--translate-x-full',
right: 'tw-translate-x-full',
top: 'tw--translate-y-full',
bottom: 'tw-translate-y-full',
left: 'tw:-translate-x-full',
right: 'tw:translate-x-full',
top: 'tw:-translate-y-full',
bottom: 'tw:translate-y-full',
}
/**
@ -29,8 +29,8 @@ export const ModalWrapper = ({
flex = 'row',
justify = 'center',
items = 'center',
bg = 'neutral lg:tw-neutral',
bgOpacity = '100 lg:tw-bg-opacity-70',
bg = 'neutral',
bgOpacity = '70',
bare = false,
keepOpenOnClick = false,
slideFrom = 'left',
@ -53,8 +53,8 @@ export const ModalWrapper = ({
// CSS classes for animation
const animation = animate
? `lg:tw-opacity-0 ${slideClasses[slideFrom]} lg:tw-translate-x-0 lg:tw-translate-y-0`
: 'tw-opacity-100 tw-translate-none'
? `tw:lg:opacity-0 ${slideClasses[slideFrom]} tw:lg:translate-x-0 tw:lg:translate-y-0`
: 'tw:opacity-100 tw:translate-none'
const stopClick = (evt) => {
/*
@ -66,10 +66,10 @@ export const ModalWrapper = ({
return (
<div
className={`tw-fixed tw-top-0 tw-left-0 tw-m-0 tw-p-0 tw-shadow tw-w-full tw-h-screen
tw-transform-all tw-duration-150 ${animation}
tw-bg-${bg} tw-bg-opacity-${bgOpacity} hover:tw-cursor-pointer
tw-flex tw-flex-${flex} tw-justify-${justify} tw-items-${items} lg:tw-p-12 tw-backdrop-blur-md`}
className={`tw:fixed tw:top-0 tw:left-0 tw:m-0 tw:p-0 tw:shadow tw:w-full tw:h-screen
tw:transform-all tw:duration-150 ${animation}
tw:bg-${bg}/${bgOpacity} tw:hover:cursor-pointer
tw:flex tw:flex-${flex} tw:justify-${justify} tw:items-${items} tw:lg:p-12 tw:backdrop-blur-md`}
onClick={close}
style={{ zIndex: 250 }}
>
@ -78,16 +78,16 @@ export const ModalWrapper = ({
) : (
<div
onClick={keepOpenOnClick ? stopClick : null}
className={`tw-z-30 tw-bg-base-100 tw-p-4 lg:tw-px-8 lg:tw-rounded-lg lg:tw-shadow-lg tw-max-h-full tw-overflow-auto hover:tw-cursor-default ${
fullWidth ? 'tw-w-full' : ''
className={`tw:z-30 tw:bg-base-100 tw:p-4 tw:lg:px-8 tw:lg:rounded-lg tw:lg:shadow-lg tw:max-h-full tw:overflow-auto tw:hover:cursor-default ${
fullWidth ? 'tw:w-full' : ''
}`}
>
{children}
<button
className="tw-fixed tw-bottom-2 tw-right-2 tw-daisy-btn tw-daisy-btn-neutral tw-daisy-btn-circle lg:tw-hidden"
className="tw:fixed tw:bottom-2 tw:right-2 tw:daisy-btn tw:daisy-btn-neutral tw:daisy-btn-circle tw:lg:hidden"
onClick={close}
>
<CloseIcon className="tw-w-8 tw-h-8" />
<CloseIcon className="tw:w-8 tw:h-8" />
</button>
</div>
)}

View file

@ -16,19 +16,19 @@ const NewLink = ({ title, Icon, description, href, Link }) => {
const linkProps = {
href,
className:
'tw-p-8 tw--ml-4 tw--mr-4 md:tw-m-0 tw-rounded-none md:tw-rounded-xl ' +
'md:tw-shadow hover:tw-bg-secondary tw-bg-base-200 hover:tw-bg-opacity-10 ' +
'tw-w-full tw-max-w-lg hover:tw-no-underline',
'tw:p-8 tw:-ml-4 tw:-mr-4 tw:md:m-0 tw:rounded-none tw:md:rounded-xl ' +
'tw:md:shadow tw:hover:bg-secondary/10 tw:bg-base-200/10 ' +
'tw:w-full tw:max-w-lg tw:hover:no-underline',
}
const inner = (
<>
<h4 className="tw-flex tw-flex-row tw-items-start tw-justify-between tw-w-full tw-m-0 tw-p-0 tw-text-inherit">
<h4 className="tw:flex tw:flex-row tw:items-start tw:justify-between tw:w-full tw:m-0 tw:p-0 tw:text-inherit">
<span>{title}</span>
<Icon className="tw-w-12 tw-h-12 tw--mt-2" stroke={1.5} />
<Icon className="tw:w-12 tw:h-12 tw:-mt-2" stroke={1.5} />
</h4>
<div
className={`tw-normal-case tw-text-base tw-font-medium tw-text-left tw-pt-2 tw-text-inherit`}
className={`tw:normal-case tw:text-base tw:font-medium tw:text-left tw:pt-2 tw:text-inherit`}
>
{description}
</div>
@ -81,8 +81,8 @@ export const NewLinks = ({ Link = false }) => {
const { account } = useAccount()
return (
<div className="tw-w-full tw-max-w-7xl">
<div className="tw-grid tw-grid-cols-1 xl:tw-grid-cols-2 tw-gap-4 tw-mb-8">
<div className="tw:w-full tw:max-w-7xl">
<div className="tw:grid tw:grid-cols-1 tw:xl:grid-cols-2 tw:gap-4 tw:mb-8">
{Object.entries(newLinks).map(([href, link]) => (
<NewLink key={href} href={href} {...link} />
))}

View file

@ -51,7 +51,7 @@ export const NewsletterSignup = ({ Link = false, noP = false, noTitle = false, n
return (
<div
className={
noBox ? '' : 'tw-w-full tw-shadow tw-border tw-rounded-lg tw-p-4 tw-bg-secondary/5'
noBox ? '' : 'tw:w-full tw:shadow tw:border tw:rounded-lg tw:p-4 tw:bg-secondary/5'
}
>
{subscribed ? (
@ -60,8 +60,8 @@ export const NewsletterSignup = ({ Link = false, noP = false, noTitle = false, n
<p>
We have sent and email to <b>{email}</b> with a link to confirm this action.
</p>
<div className="tw-ml-2 tw-pl-2 tw-border-l-4 tw-border-secondary/20">
<h6 className="tw-mt-2 tw-pb-0">Why do I need to confirm this?</h6>
<div className="tw:ml-2 tw:pl-2 tw:border-l-4 tw:border-secondary/20">
<h6 className="tw:mt-2 tw:pb-0">Why do I need to confirm this?</h6>
<small>
Without this confirmation step, anyone could attempt to {unsubscribe ? 'un' : ''}
subcribe this E-mail address {unsubscribe ? 'from' : 'to'} our newsletter.
@ -89,15 +89,15 @@ export const NewsletterSignup = ({ Link = false, noP = false, noTitle = false, n
</>
}
labelBL={
<span className="tw-flex tw-flex-row tw-items-center tw-flex-wrap tw-gap-1">
<span className="tw:flex tw:flex-row tw:items-center tw:flex-wrap tw:gap-1">
{validateEmail(email) ? (
<>
<OkIcon className="tw-text-success tw-w-5 tw-h-5" stroke={3} />
<OkIcon className="tw:text-success tw:w-5 tw:h-5" stroke={3} />
Looks great, click below to {unsubscribe ? 'un' : ''}subscribe this address
</>
) : (
<>
<WarningIcon className="tw-text-error tw-w-5 tw-h-5" /> Please enter a valid
<WarningIcon className="tw:text-error tw:w-5 tw:h-5" /> Please enter a valid
E-mail address
</>
)}
@ -108,7 +108,7 @@ export const NewsletterSignup = ({ Link = false, noP = false, noTitle = false, n
valid={validateEmail}
/>
<button
className="tw-daisy-btn tw-daisy-btn-primary tw-w-full"
className="tw:daisy-btn tw:daisy-btn-primary tw:w-full"
disabled={!validateEmail(email)}
onClick={subscribe}
>
@ -174,7 +174,7 @@ export const NewsletterUnsubscribe = ({ Link = false }) => {
</p>
<button
onClick={unsubscribe}
className="tw-daisy-btn tw-daisy-btn-primary tw-daisy-btn-large tw-w-full tw-my-4"
className="tw:daisy-btn tw:daisy-btn-primary tw:daisy-btn-large tw:w-full tw:my-4"
>
Unsubscribe
</button>

View file

@ -6,13 +6,13 @@ import { useAccount } from '@freesewing/react/hooks/useAccount'
export const PleaseSubscribe = (props = {}) => (
<div
className={`tw-max-w-7xl tw-m-auto tw-px-0 tw--mt-12 tw-mb-24 ${props.dense ? '' : 'md:tw-my-24'}`}
className={`tw:max-w-7xl tw:m-auto tw:px-0 tw:-mt-12 tw:mb-24 ${props.dense ? '' : 'tw:md:my-24'}`}
>
<div className="tw-p-1 tw-bg-gradient-to-tr tw-from-neutral tw-to-primary tw-mt-12 tw-rounded-none md:tw-rounded-lg lg:tw-rounded-xl md:tw-shadow tw-text-neutral-content tw-p-8 lg:tw-px-12 md:tw-py-0">
<div className="tw-flex tw-flex-col md:tw-gap-2 lg:tw-gap-12 md:tw-grid md:tw-grid-cols-2">
<div className="tw:p-1 tw:bg-linear-to-tr tw:from-neutral tw:to-primary tw:mt-12 tw:rounded-none tw:md:rounded-lg tw:lg:rounded-xl tw:md:shadow tw:text-neutral-content tw:p-8 tw:lg:px-12 tw:md:py-0">
<div className="tw:flex tw:flex-col tw:md:gap-2 tw:lg:gap-12 tw:md:grid tw:md:grid-cols-2">
<Plea />
<div className="tw--mt-8 md:tw-mt-0 tw-pt-0 md:tw-pt-8 tw-pb-8 lg:tw-py-12 tw-max-w-prose tw-m-auto tw-w-full tw-m-auto">
<h2 className="tw-text-inherit">Support FreeSewing</h2>
<div className="tw:-mt-8 tw:md:mt-0 tw:pt-0 tw:md:pt-8 tw:pb-8 tw:lg:py-12 tw:max-w-prose tw:m-auto tw:w-full tw:m-auto">
<h2 className="tw:text-inherit">Support FreeSewing</h2>
<Subscribe {...props} />
</div>
</div>
@ -21,8 +21,8 @@ export const PleaseSubscribe = (props = {}) => (
)
export const Plea = () => (
<div className="md:tw-pt-8 tw-pb-8 lg:tw-py-12 tw-max-w-prose tw-w-full tw-m-auto">
<h2 className="tw-text-inherit tw-mb-4">
<div className="tw:md:pt-8 tw:pb-8 tw:lg:py-12 tw:max-w-prose tw:w-full tw:m-auto">
<h2 className="tw:text-inherit tw:mb-4">
Hi friend
<span role="img"> 👋</span>
</h2>
@ -33,11 +33,11 @@ export const Plea = () => (
'Thanks in advance for considering it.',
'love',
].map((txt, i) => (
<p className="tw-text-inherit tw-font-medium tw-mb-2" key={i}>
<p className="tw:text-inherit tw:font-medium tw:mb-2" key={i}>
{txt}
</p>
))}
<Joost className="tw-ml-12 tw--mt-8 tw-w-32" />
<Joost className="tw:ml-12 tw:-mt-8 tw:w-32" />
</div>
)
@ -87,28 +87,28 @@ export const Subscribe = ({
: paypalConfig.periods
return (
<div className="tw-w-full">
<div className="tw-flex tw-flex-row tw-gap-2">
<div className="tw-daisy-form-control tw-w-full">
<label className="tw-daisy-label">
<span className="tw-daisy-label-text-alt tw-text-inherit">Your Contribution</span>
<div className="tw:w-full">
<div className="tw:flex tw:flex-row tw:gap-2">
<div className="tw:daisy-form-control tw:w-full">
<label className="tw:daisy-label">
<span className="tw:daisy-label-text-alt tw:text-inherit">Your Contribution</span>
</label>
<input
type="text"
inputMode="decimal"
placeholder="Enter amount here"
pattern="[0-9]+([.][0-9]+)?"
className="tw-daisy-input tw-daisy-input-bordered tw-w-full tw-text-base-content"
className="tw:daisy-input tw:daisy-input-bordered tw:w-full tw:text-base-content"
value={amount}
onChange={(evt) => setAmount(evt.target.value)}
/>
</div>
<div className="tw-form-control tw-w-24">
<label className="tw-daisy-label">
<span className="tw-daisy-label-text-alt tw-text-inherit">Currency</span>
<div className="tw:form-control tw:w-24">
<label className="tw:daisy-label">
<span className="tw:daisy-label-text-alt tw:text-inherit">Currency</span>
</label>
<select
className="tw-daisy-select tw-daisy-select-bordered tw-text-base-content"
className="tw:daisy-select tw:daisy-select-bordered tw:text-base-content"
defaultValue={currency}
onChange={(evt) => setCurrency(evt.target.value)}
>
@ -121,13 +121,13 @@ export const Subscribe = ({
</div>
</div>
<div>
<label className="tw-daisy-label">
<div className="tw-daisy-label-text-alt tw-text-inherit tw-flex tw-flex-row tw-flex-wrap tw-gap-1">
<span className="tw-hidden lg:tw-inline">Presets:</span>
<label className="tw:daisy-label">
<div className="tw:daisy-label-text-alt tw:text-inherit tw:flex tw:flex-row tw:flex-wrap tw:gap-1">
<span className="tw:hidden tw:lg:inline">Presets:</span>
{amounts.map((val) => (
<button
key={val}
className="tw-font-bold tw-underline tw-decoration-2 tw-px-1 hover:tw-decoration-4"
className="tw:font-bold tw:underline tw:decoration-2 tw:px-1 tw:hover:decoration-4"
onClick={() => setAmount(val)}
>
{val}
@ -136,26 +136,26 @@ export const Subscribe = ({
</div>
</label>
</div>
<div className="tw-grid tw-grid-cols-2 md:tw-grid-cols-3 tw-gap-2 tw-mt-2">
<div className="tw:grid tw:grid-cols-2 tw:md:grid-cols-3 tw:gap-2 tw:mt-2">
{periods.map((val) => (
<div
className={`tw-daisy-form-control tw-border tw-border-solid tw-border-inherit tw-rounded tw-px-1 tw-flex tw-flex-col tw-justify-center ${
period === val ? 'tw-bg-base-100 tw-text-base-content' : ''
className={`tw:daisy-form-control tw:border tw:border-solid tw:border-inherit tw:rounded tw:px-1 tw:flex tw:flex-col tw:justify-center ${
period === val ? 'tw:bg-base-100 tw:text-base-content' : ''
}`}
key={val}
>
<label className="tw-daisy-label tw-cursor-pointer tw-py-1.5 tw-flex tw-flex-row tw-gap-2 tw-items-center tw-overflow-clip tw-justify-start">
<label className="tw:daisy-label tw:cursor-pointer tw:py-1.5 tw:flex tw:flex-row tw:gap-2 tw:items-center tw:overflow-clip tw:justify-start">
<input
type="radio"
name="period"
className={`tw-daisy-radio checked:tw-bg-${color} tw-border-${color} tw-daisy-radio-xs lg:tw-daisy-radio-sm tw-bg-secondary/20`}
className={`tw:daisy-radio checked:tw:bg-${color} tw:border-${color} tw:daisy-radio-xs lg:tw:daisy-radio-sm tw:bg-secondary/20`}
value={val}
onChange={() => setPeriod(val)}
checked={val === period ? 1 : 0}
/>
<span
className={`tw-daisy-label-text tw-text-inherit tw-text-xs lg:tw-text-sm ${
val === period ? 'tw-font-bold' : ''
className={`tw:daisy-label-text tw:text-inherit tw:text-xs tw:lg:text-sm ${
val === period ? 'tw:font-bold' : ''
}`}
>
{paypalConfig.periodLabels[val]}
@ -173,16 +173,16 @@ export const Subscribe = ({
>
<PaypalFormBody {...{ currency, amount, period }} />
<button
className={`tw-daisy-btn tw-daisy-btn-${color} tw-w-full tw-mt-4`}
className={`tw:daisy-btn tw:daisy-btn-${color} tw:w-full tw:mt-4`}
disabled={!(Number(amount) > 0)}
type="submit"
>
{period === 'x' ? 'Donate' : 'Subscribe'}
</button>
<p className="tw-text-center tw-text-sm tw-text-neutral-content tw-mt-2 tw-opacity-80">
<p className="tw:text-center tw:text-sm tw:text-neutral-content tw:mt-2 tw:opacity-80">
Don&apos;t have a PayPal account?
<a href="https://ko-fi.com/freesewing" target="_BLANK" className={linkClasses}>
<b className="tw-text-neutral-content tw-pl-2">Ko-fi.com/FreeSewing</b>
<b className="tw:text-neutral-content tw:pl-2">Ko-fi.com/FreeSewing</b>
</a>
</p>
</form>
@ -190,7 +190,7 @@ export const Subscribe = ({
)
}
export const Joost = ({ className = 'tw-w-32', stroke = 0 }) => (
export const Joost = ({ className = 'tw:w-32', stroke = 0 }) => (
<svg
xmlns="http://www.w3.org/2000/svg"
fill="currentColor"

View file

@ -44,22 +44,22 @@ export const Popout = (props) => {
return props.compact ? (
<div
className={`tw-relative ${
props.dense ? 'tw-my-1' : 'tw-my-8'
} tw-bg-${color} tw-bg-opacity-5 tw--ml-4 tw--mr-4 sm:tw-ml-0 sm:tw-mr-0 ${className}`}
className={`tw:relative ${
props.dense ? 'tw:my-1' : 'tw:my-8'
} tw:bg-${color}/5 tw:-ml-4 tw:-mr-4 tw:sm:ml-0 tw:sm:mr-0 ${className}`}
>
<div
className={`
tw-border-y-4 sm:tw-border-0 sm:tw-border-l-4 tw-px-4
tw-shadow tw-text-base border-${color}
tw-flex tw-flex-row tw-items-center
tw:border-y-4 tw:sm:border-0 tw:sm:border-l-4 tw:px-4
tw:shadow tw:text-base border-${color}
tw:flex tw:flex-row tw:items-center
`}
>
<div className={`tw-font-bold tw-uppercase tw-text-${color}`}>
<div className={`tw:font-bold tw:uppercase tw:text-${color}`}>
{props.title || (
<>
<span>{type.toUpperCase()}</span>
<span className="tw-px-3">|</span>
<span className="tw:px-3">|</span>
</>
)}
</div>
@ -68,23 +68,23 @@ export const Popout = (props) => {
</div>
) : (
<div
className={`tw-relative tw-my-8 tw-bg-${color} tw-bg-opacity-5 tw--ml-4 tw--mr-4 sm:tw-ml-0 sm:tw-mr-0 ${className}`}
className={`tw:relative tw:my-8 tw:bg-${color}/5 tw:-ml-4 tw:-mr-4 tw:sm:ml-0 tw:sm:mr-0 ${className}`}
>
<div
className={`
tw-border-y-4 tw-border-x-0 sm:tw-border-0 sm:tw-border-l-4 tw-px-6 sm:tw-px-8 tw-py-4 sm:tw-py-2
tw-shadow tw-text-base tw-border-${color} tw-border-solid
tw:border-y-4 tw:border-x-0 tw:sm:border-0 tw:sm:border-l-4 tw:px-6 tw:sm:px-8 tw:py-4 tw:sm:py-2
tw:shadow tw:text-base tw:border-${color} tw:border-solid
`}
>
<div
className={`tw-font-bold tw-flex tw-flex-row tw-gap-1 tw-items-end tw-justify-between`}
className={`tw:font-bold tw:flex tw:flex-row tw:gap-1 tw:items-end tw:justify-between`}
>
<div>
<span className={`tw-font-bold tw-uppercase tw-text-${color}`}>
<span className={`tw:font-bold tw:uppercase tw:text-${color}`}>
{props.title ? props.title : type === 'tldr' ? 'TL;DR' : type.toUpperCase()}
</span>
<span className={`tw-font-normal tw-text-base text-${color}`}>
{type === 'tw-comment' && (
<span className={`tw:font-normal tw:text-base text-${color}`}>
{type === 'tw:comment' && (
<>
{' '}
by <b>{props.by}</b>
@ -93,14 +93,14 @@ export const Popout = (props) => {
</span>
</div>
{props.hideable && (
<button onClick={() => setHide(true)} className="hover:tw-text-secondary" title="Close">
<button onClick={() => setHide(true)} className="tw:hover:text-secondary" title="Close">
<CloseIcon />
</button>
)}
</div>
<div className="tw-py-1 first:tw-mt-0 tw-popout-content">{props.children}</div>
<div className="tw:py-1 tw:first:mt-0 tw:popout-content">{props.children}</div>
{type === 'comment' && (
<div className={`tw-font-bold tw-italic text-${color}`}>{props.by}</div>
<div className={`tw:font-bold tw:italic text-${color}`}>{props.by}</div>
)}
</div>
</div>

View file

@ -69,14 +69,14 @@ export const UserProfile = ({
return (
<>
<div className="tw-w-full tw-flex tw-flex-row tw-flex-wrap tw-items-center tw-gap-4">
<div className="tw:w-full tw:flex tw:flex-row tw:flex-wrap tw:items-center tw:gap-4">
<Avatar ihash={data.ihash} />
<div className="tw-flex tw-flex-col tw-items-start tw-gap-1">
<div className="tw:flex tw:flex-col tw:items-start tw:gap-1">
<h2>{data.username}</h2>
<KeyVal k="role" val={data.role} />
</div>
</div>
<div className="tw-my-4 tw-border-l-4 tw-pl-2">
<div className="tw:my-4 tw:border-l-4 tw:pl-2">
<b>Permalink: </b>
<Link href={`/users?id=${ruid}`}>{`freesewing.eu/users?id=${ruid}`}</Link>
</div>
@ -100,7 +100,7 @@ export const Avatar = ({ ihash }) => {
<ModalWrapper>
<img
src={cloudflareImageUrl({ id: `uid-${ihash}`, variant: 'public' })}
className="tw-max-w-full tw-max-h-screen"
className="tw:max-w-full tw:max-h-screen"
/>
</ModalWrapper>
)
@ -108,7 +108,7 @@ export const Avatar = ({ ihash }) => {
>
<img
src={cloudflareImageUrl({ id: `uid-${ihash}`, variant: 'sq500' })}
className="tw-w-32 tw-h-32 tw-rounded-full tw-shadow tw-border-current tw-border-4"
className="tw:w-32 tw:h-32 tw:rounded-full tw:shadow tw:border-current tw:border-4"
/>
</button>
)

View file

@ -15,15 +15,15 @@ import { H1, H2, H3 } from '@freesewing/react/components/Heading'
const ConsentForm = () => null
const Wrap = ({ children }) => (
<div className="tw-m-auto tw-max-w-xl tw-text-center tw-mt-8 tw-p-8">{children}</div>
<div className="tw:m-auto tw:max-w-xl tw:text-center tw:mt-8 tw:p-8">{children}</div>
)
const ContactSupport = ({ Link = false }) => {
if (!Link) Link = DefaultLink
return (
<div className="tw-flex tw-flex-row tw-items-center tw-justify-center tw-gap-4 tw-mt-8">
<Link href="/support" className="tw-daisy-btn tw-daisy-btn-success tw-w-full">
<div className="tw:flex tw:flex-row tw:items-center tw:justify-center tw:gap-4 tw:mt-8">
<Link href="/support" className="tw:daisy-btn tw:daisy-btn-success tw:w-full">
Contact Support
</Link>
</div>
@ -38,17 +38,17 @@ const AuthRequired = ({ Link, banner }) => {
{banner}
<H3>Authentication Required</H3>
<p>This functionality requires a FreeSewing account</p>
<div className="tw-grid tw-grid-cols-1 md:tw-grid-cols-2 tw-gap-2 tw-mt-8">
<div className="tw:grid tw:grid-cols-1 tw:md:grid-cols-2 tw:gap-2 tw:mt-8">
<Link
href="/signup"
className={`${horFlexClasses} tw-daisy-btn tw-daisy-btn-secondary tw-w-full`}
className={`${horFlexClasses} tw:daisy-btn tw:daisy-btn-secondary tw:w-full`}
>
<PlusIcon />
Sign Up
</Link>
<Link
href="/signin"
className={`${horFlexClasses} tw-daisy-btn tw-daisy-btn-secondary tw-daisy-btn-outline tw-w-full`}
className={`${horFlexClasses} tw:daisy-btn tw:daisy-btn-secondary tw:daisy-btn-outline tw:w-full`}
>
<LockIcon />
Sign In
@ -67,8 +67,8 @@ const AccountInactive = ({ Link, banner }) => {
<H3>Account Inactive</H3>
<p>You must activate your account via the signup link we sent you.</p>
<p>If you cannot find the link, you can receive a new one by signing up again.</p>
<div className="tw-flex tw-flex-row tw-items-center tw-justify-center tw-gap-4 tw-mt-8">
<Link href="/signup" className="tw-daisy-btn tw-daisy-btn-primary tw-w-full">
<div className="tw:flex tw:flex-row tw:items-center tw:justify-center tw:gap-4 tw:mt-8">
<Link href="/signup" className="tw:daisy-btn tw:daisy-btn-primary tw:w-full">
Sign Up
</Link>
</div>
@ -142,7 +142,7 @@ const ConsentLacking = ({ banner, refresh }) => {
return (
<Wrap>
<div className="tw-text-left">
<div className="tw:text-left">
{banner}
<ConsentForm submit={updateConsent} />
</div>
@ -204,11 +204,11 @@ export const RoleBlock = ({ children, user = false, Link = false }) => {
if (!ready) return <Spinner />
const banner = impersonating ? (
<div className="tw-bg-warning tw-rounded-lg tw-shadow tw-py-4 tw-px-6 tw-flex tw-flex-row tw-items-center tw-gap-4 tw-justify-between">
<span className="tw-text-base-100 tw-text-left">
<div className="tw:bg-warning tw:rounded-lg tw:shadow tw:py-4 tw:px-6 tw:flex tw:flex-row tw:items-center tw:gap-4 tw:justify-between">
<span className="tw:text-base-100 tw:text-left">
Hi <b>{impersonating.admin}</b>, you are currently impersonating <b>{impersonating.user}</b>
</span>
<button className="tw-daisy-btn tw-daisy-btn-neutral" onClick={stopImpersonating}>
<button className="tw:daisy-btn tw:daisy-btn-neutral" onClick={stopImpersonating}>
Stop Impersonating
</button>
</div>

View file

@ -151,13 +151,13 @@ export const SignIn = ({ onSuccess = false, silent = false }) => {
}
}
const btnClasses = `tw-daisy-btn tw-capitalize tw-w-full tw-mt-4 ${
signInFailed ? 'tw-daisy-btn-warning' : 'tw-daisy-btn-primary'
} tw-transition-colors tw-ease-in-out tw-duration-300 ${horFlexClassesNoSm}`
const btnClasses = `tw:daisy-btn tw:capitalize tw:w-full tw:mt-4 ${
signInFailed ? 'tw:daisy-btn-warning' : 'tw:daisy-btn-primary'
} tw:transition-colors tw:ease-in-out tw:duration-300 ${horFlexClassesNoSm}`
const noBueno = (
<>
<WarningIcon />
<span className="tw-pl-2">{signInFailed}</span>
<span className="tw:pl-2">{signInFailed}</span>
<WarningIcon />
</>
)
@ -166,22 +166,22 @@ export const SignIn = ({ onSuccess = false, silent = false }) => {
return (
<WrapForm>
<H1>Email Sent</H1>
<p className="tw-text-inherit tw-text-lg tw-text-center">
<p className="tw:text-inherit tw:text-lg tw:text-center">
Go check your inbox for an email from <b>FreeSewing.org</b>
</p>
<p className="tw-text-inherit tw-text-lg tw-text-center">
<p className="tw:text-inherit tw:text-lg tw:text-center">
Click the sign-in link in that email to sign in to your FreeSewing account.
</p>
<div className="tw-flex tw-flex-row tw-gap-4 tw-items-center tw-justify-center tw-p-8">
<div className="tw:flex tw:flex-row tw:gap-4 tw:items-center tw:justify-center tw:p-8">
<button
className="tw-daisy-btn tw-daisy-btn-outline tw-daisy-btn-sm"
className="tw:daisy-btn tw:daisy-btn-outline tw:daisy-btn-sm"
onClick={() => setMagicLinkSent(false)}
>
Back
</button>
<Link
href="/support"
className="tw-daisy-btn tw-daisy-btn-outline tw-daisy-btn-sm hover:tw-no-underline"
className="tw:daisy-btn tw:daisy-btn-outline tw:daisy-btn-sm tw:hover:no-underline"
>
Contact support
</Link>
@ -195,11 +195,11 @@ export const SignIn = ({ onSuccess = false, silent = false }) => {
{...{ mfaCode, setMfaCode }}
onSubmit={signinHandler}
post={
<div className="tw-flex tw-flex-row tw-gap-4 tw-items-center tw-justify-center tw-p-8">
<button className="tw-daisy-btn tw-daisy-btn-ghost" onClick={() => setMfa(false)}>
<div className="tw:flex tw:flex-row tw:gap-4 tw:items-center tw:justify-center tw:p-8">
<button className="tw:daisy-btn tw:daisy-btn-ghost" onClick={() => setMfa(false)}>
Back
</button>
<Link href="/support" className="tw-daisy-btn tw-daisy-btn-ghost">
<Link href="/support" className="tw:daisy-btn tw:daisy-btn-ghost">
Contact support
</Link>
</div>
@ -222,7 +222,7 @@ export const SignIn = ({ onSuccess = false, silent = false }) => {
)}
{magicLink ? (
<button
className={`${btnClasses} tw-daisy-btn-lg`}
className={`${btnClasses} tw:daisy-btn-lg`}
tabIndex="-1"
role="button"
onClick={signinHandler}
@ -231,11 +231,11 @@ export const SignIn = ({ onSuccess = false, silent = false }) => {
noBueno
) : (
<>
<span className="tw-hidden lg:tw-block">
<span className="tw:hidden tw:lg:block">
<EmailIcon />
</span>
<span className="tw-pl-2">Email me a sign-in link</span>
<span className="tw-hidden lg:tw-block">
<span className="tw:pl-2">Email me a sign-in link</span>
<span className="tw:hidden tw:lg:block">
<EmailIcon />
</span>
</>
@ -255,11 +255,11 @@ export const SignIn = ({ onSuccess = false, silent = false }) => {
noBueno
) : (
<>
<span className="tw-hidden lg:tw-block">
<span className="tw:hidden tw:lg:block">
<KeyIcon />
</span>
<span className="tw-pl-2">Sign in</span>
<span className="tw-hidden lg:tw-block">
<span className="tw:pl-2">Sign in</span>
<span className="tw:hidden tw:lg:block">
<LockIcon />
</span>
</>
@ -268,19 +268,19 @@ export const SignIn = ({ onSuccess = false, silent = false }) => {
</>
)}
<button
className={`tw-block md:tw-flex md:tw-flex-row md:tw-justify-between md:tw-items-center tw-daisy-btn tw-daisy-btn-primary tw-daisy-btn-outline tw-w-full tw-mt-8`}
className={`tw:block tw:md:flex tw:md:flex-row tw:md:justify-between tw:md:items-center tw:daisy-btn tw:daisy-btn-primary tw:daisy-btn-outline tw:w-full tw:mt-8`}
onClick={() => setMagicLink(!magicLink)}
>
<span className="tw-hidden lg:tw-block">{magicLink ? <LockIcon /> : <EmailIcon />}</span>
<span className="tw:hidden tw:lg:block">{magicLink ? <LockIcon /> : <EmailIcon />}</span>
{magicLink ? 'Use your password' : 'Email me a sign-in link'}
<span className="tw-hidden lg:tw-block">{magicLink ? <KeyIcon /> : <EmailIcon />}</span>
<span className="tw:hidden tw:lg:block">{magicLink ? <KeyIcon /> : <EmailIcon />}</span>
</button>
<div className="tw-grid tw-grid-cols-1 md:tw-grid-cols-2 tw-gap-2 tw-items-center tw-mt-2">
<div className="tw:grid tw:grid-cols-1 tw:md:grid-cols-2 tw:gap-2 tw:items-center tw:mt-2">
{['Google', 'Github'].map((provider) => (
<button
key={provider}
id={provider}
className={`${horFlexClasses} tw-daisy-btn tw-daisy-btn-secondary`}
className={`${horFlexClasses} tw:daisy-btn tw:daisy-btn-secondary`}
onClick={() => initOauth(provider)}
>
{provider === 'Google' ? <GoogleIcon stroke={0} /> : <GitHubIcon />}
@ -290,7 +290,7 @@ export const SignIn = ({ onSuccess = false, silent = false }) => {
</div>
{seenBefore ? (
<button
className={`${horFlexClasses} tw-daisy-btn tw-daisy-btn-neutral tw-daisy-btn-outline tw-mt-2 tw-w-full`}
className={`${horFlexClasses} tw:daisy-btn tw:daisy-btn-neutral tw:daisy-btn-outline tw:mt-2 tw:w-full`}
onClick={() => setSeenUser(false)}
>
<UserIcon />
@ -298,10 +298,10 @@ export const SignIn = ({ onSuccess = false, silent = false }) => {
</button>
) : (
<Link
className={`${horFlexClasses} tw-daisy-btn tw-daisy-btn-lg tw-daisy-btn-neutral tw-mt-2 hover:tw-text-neutral-content hover:tw-no-underline`}
className={`${horFlexClasses} tw:daisy-btn tw:daisy-btn-lg tw:daisy-btn-neutral tw:mt-2 tw:hover:text-neutral-content tw:hover:no-underline`}
href="/signup"
>
<FreeSewingIcon className="tw-h-10 tw-w-10" />
<FreeSewingIcon className="tw:h-10 tw:w-10" />
Sign up here
</Link>
)}
@ -309,12 +309,12 @@ export const SignIn = ({ onSuccess = false, silent = false }) => {
)
}
const WrapForm = ({ children }) => <div className="tw-text-center tw-py-12">{children}</div>
const WrapForm = ({ children }) => <div className="tw:text-center tw:py-12">{children}</div>
const MfaForm = ({ mfaCode, setMfaCode, onSubmit, post = [] }) => (
<WrapForm>
<H1>MFA Code</H1>
<p className="tw-text-inherit tw-text-lg tw-text-center">
<p className="tw:text-inherit tw:text-lg tw:text-center">
Please provide a one-time MFA code, or a backup scratch code
</p>
<MfaInput
@ -323,16 +323,16 @@ const MfaForm = ({ mfaCode, setMfaCode, onSubmit, post = [] }) => (
value={mfaCode}
/>
<button
className={`tw-daisy-btn tw-capitalize tw-w-full tw-mt-4 tw-daisy-btn-primary ${horFlexClassesNoSm}`}
className={`tw:daisy-btn tw:capitalize tw:w-full tw:mt-4 tw:daisy-btn-primary ${horFlexClassesNoSm}`}
tabIndex="-1"
role="button"
onClick={onSubmit}
>
<span className="tw-hidden lg:tw-block">
<span className="tw:hidden tw:lg:block">
<KeyIcon />
</span>
<span className="tw-pl-2">Sign In</span>
<span className="tw-hidden lg:tw-block">
<span className="tw:pl-2">Sign In</span>
<span className="tw:hidden tw:lg:block">
<LockIcon />
</span>
</button>
@ -428,7 +428,7 @@ export const SignInConfirmation = ({ onSuccess = false }) => {
return (
<>
<h1>One moment please</h1>
<Spinner className="tw-w-8 tw-h-8 tw-m-auto tw-animate-spin" />
<Spinner className="tw:w-8 tw:h-8 tw:m-auto tw:animate-spin" />
</>
)
@ -438,7 +438,7 @@ export const SignInConfirmation = ({ onSuccess = false }) => {
/*
* This is the generic component that will handle the Oauth callback
*/
function OauthCallback({ provider = false }) {
export const OauthCallback = ({ provider = false }) => {
const [error, setError] = useState(false)
const backend = useBackend()
const { setAccount, setToken, setSeenUser } = useAccount()
@ -474,7 +474,7 @@ function OauthCallback({ provider = false }) {
) : (
<>
<h2>One moment please</h2>
<Spinner className="tw-w-8 tw-h-8 tw-m-auto tw-animate-spin" />
<Spinner className="tw:w-8 tw:h-8 tw:m-auto tw:animate-spin" />
</>
)
}

Some files were not shown because too many files have changed in this diff Show more