{"id":13525675,"url":"https://github.com/nesterow/tailored","last_synced_at":"2025-05-03T03:31:31.253Z","repository":{"id":65698565,"uuid":"592504732","full_name":"nesterow/tailored","owner":"nesterow","description":"Isomorphic utilities, components and hooks for Fresh and Preact.","archived":false,"fork":false,"pushed_at":"2023-03-25T16:54:49.000Z","size":414,"stargazers_count":25,"open_issues_count":1,"forks_count":2,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-04-25T02:48:06.472Z","etag":null,"topics":["deno","jsx","partial-hydration","preact","typescript"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":false,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/nesterow.png","metadata":{"files":{"readme":"readme.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-01-23T21:41:53.000Z","updated_at":"2025-03-21T00:11:05.000Z","dependencies_parsed_at":"2024-01-11T14:26:52.075Z","dependency_job_id":null,"html_url":"https://github.com/nesterow/tailored","commit_stats":null,"previous_names":[],"tags_count":10,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nesterow%2Ftailored","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nesterow%2Ftailored/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nesterow%2Ftailored/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nesterow%2Ftailored/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/nesterow","download_url":"https://codeload.github.com/nesterow/tailored/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":252137567,"owners_count":21700239,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["deno","jsx","partial-hydration","preact","typescript"],"created_at":"2024-08-01T06:01:20.991Z","updated_at":"2025-05-03T03:31:30.824Z","avatar_url":"https://github.com/nesterow.png","language":"TypeScript","funding_links":[],"categories":["Uncategorized"],"sub_categories":["Uncategorized"],"readme":"# Tailored Components\n\n![test](https://github.com/nesterow/tailored/actions/workflows/test.yml/badge.svg?branch=main)\n\n_Isomorphic utilities, components and hooks for [Fresh](https://fresh.deno.dev)\nand [Preact](https://preactjs.com)._\n\n## Components\n\n_The unstyled Preact components._\n\n### Popover\n\nCompletely unstyled popover for preact built with\n[Floating UI](https://floating-ui.com/docs/getting-started)\n\n```typescript\nimport { useRef } from \"preact/hooks\";\nimport Popover from \"https://deno.land/x/tailored/components/Popover.tsx\";\n\nexport default function App() {\n  const ref = useRef(null);\n  return (\n    \u003cdiv\u003e\n      \u003cbutton ref={ref}\u003eOpen popover\u003c/button\u003e\n      \u003cPopover\n        target={ref}\n        trigger=\"click\"\n        className=\"bg-white shadow-lg rounded-lg p-4\"\n        clickOutside\n      \u003e\n        \u003cdiv\u003eContent\u003c/div\u003e\n      \u003c/Popover\u003e\n    \u003c/div\u003e\n  );\n}\n```\n\n[source / typedefs](https://deno.land/x/tailored/components/Popover.tsx?source)\n\n### ToggleClass\n\nA component that toggles a class on a target element. The target element can be\na ref or a selector.\n\n```typescript\nimport { tw } from \"twind/core\";\nimport ToggleClass from \"https://deno.land/x/tailored/components/ToggleClass.tsx\";\n\nexport default function MenuButton(props: MenuButtonProps) {\n  return (\n    \u003cToggleClass\n      target=\"[mobile-menu]\"\n      toggleAddClass={tw(\"flex\")}\n      toggleRemoveClass={tw(\"visibility-hidden\")}\n    \u003e\n      \u003cMenuIcon /\u003e\n    \u003c/ToggleClass\u003e\n  );\n}\n```\n\n[source / typedefs](https://deno.land/x/tailored/components/ToggleClass.tsx?source)\n\n### LazyHydrate\n\nHydrate components only when they are in the viewport or when an event is\nemitted. You can control hydration by emmiting a custom event on the document.\nBy default, the component supports the `visible` event which is implemented with\nan intersection observer.\n\n```typescript\nimport { tw } from \"twind/core\";\nimport LazyHydrate from \"https://deno.land/x/tailored/components/LazyHydrate.tsx\";\n\nexport default function MenuButton(props: MenuButtonProps) {\n  return (\n    \u003cLazyHydrate\n      id=\"lazy123\"\n      event=\"visible\"\n      classNames={[\n        \"x-non-hydrated\",\n        \"x-hydrated\",\n      ]}\n    \u003e\n      \u003cMyComplexComponent {...props} /\u003e\n    \u003c/LazyHydrate\u003e\n  );\n}\n```\n\n[source / typedefs](https://deno.land/x/tailored/components/LazyHydrate.tsx?source)\n\n---\n\n## Fresh plugins\n\n_Useful plugins for Fresh._\n\n### Context plugin\n\nA plugin that enables the use of global Preact Context in islands. Current\nverion supports only one provider and only JSON-serializable values.\n\n```typescript\nimport Context from \"./context.ts\";\nimport contextPlugin from \"tailored/plugins/context.ts\";\n\nawait start(manifest, {\n  plugins: [\n    contextPlugin(\n      Context,\n      new URL(\"./context.ts\", import.meta.url).href,\n    ),\n  ],\n});\n```\n\n[context.ts](./context.ts) |\n[source](https://deno.land/x/tailored/plugins/context.ts?source)\n\n### Client plugin\n\nUsed for client-only code:\n\n```typescript\nimport clientPlugin from \"tailored/plugins/client.ts\";\n\nawait start(manifest, {\n  plugins: [\n    clientPlugin(\n      new URL(\"./client.ts\", import.meta.url).href,\n    ),\n  ],\n});\n```\n\n[client.ts](./client.ts) |\n[source](https://deno.land/x/tailored/plugins/client.ts?source)\n\n### Preloader plugin\n\nShow a progress indicator while the page is loading:\n\n```typescript\nimport preloaderPlugin from \"tailored/plugins/preloader.ts\";\n\nawait start(manifest, {\n  plugins: [\n    preloaderPlugin(\"#48d1cc\", \"4px\"),\n  ],\n});\n```\n\n### Twind v1 plugin\n\nTwind v1 plugin for Fresh. Based on the official fresh plugin for twind v0.x\n\n[Plugin](./main.ts) | [Config](./twind.config.ts) |\n[source](https://deno.land/x/tailored/plugins/twind.ts?source)\n\n---\n\n## Preact Hooks\n\n_A set of useful hooks for preact._\n\n- [useContextFetch(ctx)](https://deno.land/x/tailored/hooks/useContextFetch.ts?source)\n  \u003e Retutns fetch function with set headers from context: `{headers: {}}`\n- [useClickOutside(callback, refOrSelector, eventType=\"click\")](https://deno.land/x/tailored/hooks/useClickOutside.ts?source)\n  \u003e Handle click outside of an element set by ref or selector.\n- [useCssPlayEnd(onFinish, ref, inputs=[])](https://deno.land/x/tailored/hooks/useCssPlayEnd.ts?source)\n  \u003e Handle the end of a CSS animation or/and transition. At the time doesn't\n  \u003e handle infinite animations.\n- [useDebounceCallback(callback, delay, inputs=[])](https://deno.land/x/tailored/hooks/useDebounceCallback.ts?source)\n  \u003e Returns an object with a debounced version of the `callback`, `immediate`\n  \u003e and `cancel`.\n- [useEventListener(eventName, handler, elementRef, options)](https://deno.land/x/tailored/hooks/useEventListener.ts?source)\n  \u003e Handles adding event listener to an element or a set of elements\n  \u003e (elementRef).\n- [usePosition(ref, options)](https://deno.land/x/tailored/hooks/usePosition.ts?source)\n  \u003e Calculate position of a floating element. Ported from @floating-ui/react-dom\n- [useI18n(ctx)](https://deno.land/x/tailored/hooks/useI18n.ts?source)\n  \u003e Use translations set from context: `{lc: {en: {}}, lang: \"en\"}`\n\n---\n\n## Development\n\nStart the project:\n\n```bash\ndeno task dev\n```\n\nThis will watch the project directory and restart as necessary.\n\n## Testing\n\n```bash\nPUPPETEER_PRODUCT=chrome deno run -A --unstable https://deno.land/x/puppeteer@16.2.0/install.ts\ndeno task test\n```\n\n## License\n\nMIT\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnesterow%2Ftailored","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnesterow%2Ftailored","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnesterow%2Ftailored/lists"}