{"id":16770544,"url":"https://github.com/askirmas/react-classnaming","last_synced_at":"2025-04-08T06:47:47.978Z","repository":{"id":57124911,"uuid":"336554917","full_name":"askirmas/react-classnaming","owner":"askirmas","description":"Tools to establish CSS classes as an explicit abstraction layer and to handle it as an interface between React and CSSStyleDeclaration","archived":false,"fork":false,"pushed_at":"2021-03-19T15:55:07.000Z","size":5860,"stargazers_count":1,"open_issues_count":15,"forks_count":0,"subscribers_count":3,"default_branch":"main","last_synced_at":"2024-04-25T18:21:35.868Z","etag":null,"topics":["bem","classname","classnames","classnaming","css","css-classes","css-modules","declarative","material","multiple","react","typescript"],"latest_commit_sha":null,"homepage":"https://npmjs.com/package/react-classnaming","language":"TypeScript","has_issues":true,"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/askirmas.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}},"created_at":"2021-02-06T14:22:00.000Z","updated_at":"2023-02-20T08:38:13.000Z","dependencies_parsed_at":"2022-08-31T08:20:28.294Z","dependency_job_id":null,"html_url":"https://github.com/askirmas/react-classnaming","commit_stats":null,"previous_names":["askirmas/classnaming"],"tags_count":21,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/askirmas%2Freact-classnaming","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/askirmas%2Freact-classnaming/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/askirmas%2Freact-classnaming/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/askirmas%2Freact-classnaming/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/askirmas","download_url":"https://codeload.github.com/askirmas/react-classnaming/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247792920,"owners_count":20996896,"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":["bem","classname","classnames","classnaming","css","css-classes","css-modules","declarative","material","multiple","react","typescript"],"created_at":"2024-10-13T06:24:36.780Z","updated_at":"2025-04-08T06:47:47.955Z","avatar_url":"https://github.com/askirmas.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# [react-classnaming](github.com/askirmas/react-classnaming) \u003cimg src=\"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9Ii0xMS41IC0xMC4yMzE3NCAyMyAyMC40NjM0OCI+CiAgPHRpdGxlPlJlYWN0IExvZ288L3RpdGxlPgogIDxjaXJjbGUgY3g9IjAiIGN5PSIwIiByPSIyLjA1IiBmaWxsPSIjNjFkYWZiIi8+CiAgPGcgc3Ryb2tlPSIjNjFkYWZiIiBzdHJva2Utd2lkdGg9IjEiIGZpbGw9Im5vbmUiPgogICAgPGVsbGlwc2Ugcng9IjExIiByeT0iNC4yIi8+CiAgICA8ZWxsaXBzZSByeD0iMTEiIHJ5PSI0LjIiIHRyYW5zZm9ybT0icm90YXRlKDYwKSIvPgogICAgPGVsbGlwc2Ugcng9IjExIiByeT0iNC4yIiB0cmFuc2Zvcm09InJvdGF0ZSgxMjApIi8+CiAgPC9nPgo8L3N2Zz4K\" alt=\"react\" height=\"56px\" align=\"right\" /\u003e\u003cimg src=\"https://raw.githubusercontent.com/microsoft/TypeScript-Website/f407e1ae19e5e990d9901ac8064a32a8cc60edf0/packages/typescriptlang-org/static/branding/ts-logo-128.svg\" alt=\"TypeScript\" height=\"56px\" align=\"right\"/\u003e\u003cimg src=\"https://upload.wikimedia.org/wikipedia/commons/d/d5/CSS3_logo_and_wordmark.svg\" alt=\"css\" height=\"56px;\" align=\"right\"/\u003e\n\nTools to establish CSS classes as an explicit [abstraction layer](https://en.wikipedia.org/wiki/Abstraction_layer \"a way of hiding the working details of a subsystem, allowing the separation of concerns to facilitate interoperability\") and to handle it as an [interface](https://en.wikipedia.org/wiki/Interface_(computing) \"a shared boundary across which two or more separate components of a computer system exchange information\") between React and [CSSStyleDeclaration](https://developer.mozilla.org/en-US/docs/Web/API/CSSStyleDeclaration \"exposes style information and various style-related methods and properties\"). \n\n[![build@ci](https://github.com/askirmas/react-classnaming/workflows/build/badge.svg)](https://github.com/askirmas/react-classnaming/actions)\n[![codecov](https://codecov.io/gh/askirmas/react-classnaming/branch/main/graph/badge.svg?token=JDPWYS3ZT6)](https://codecov.io/gh/askirmas/react-classnaming)\n[![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=askirmas_react-classnaming\u0026metric=alert_status)](https://sonarcloud.io/dashboard?id=askirmas_react-classnaming)\n[![Maintainability](https://api.codeclimate.com/v1/badges/6d424425b4bd07a77a43/maintainability)](https://codeclimate.com/github/askirmas/react-classnaming/issues)\n[![Scrutinizer Code Quality](https://img.shields.io/scrutinizer/quality/g/askirmas/react-classnaming/main)](https://scrutinizer-ci.com/g/askirmas/react-classnaming/)\n[![DeepScan grade](https://deepscan.io/api/teams/13158/projects/16163/branches/340904/badge/grade.svg)](https://deepscan.io/dashboard#view=project\u0026tid=13158\u0026pid=16163\u0026bid=340904)\n[![CodeFactor](https://www.codefactor.io/repository/github/askirmas/react-classnaming/badge)](https://www.codefactor.io/repository/github/askirmas/react-classnaming)\n\n[![dependencies Status](https://status.david-dm.org/gh/askirmas/react-classnaming.svg)](https://david-dm.org/askirmas/react-classnaming)\n[![version](https://img.shields.io/npm/v/react-classnaming)](https://www.npmjs.com/package/react-classnaming)\n[![license](https://img.shields.io/npm/l/react-classnaming)](https://github.com/askirmas/react-classnaming/blob/main/LICENSE)\n\n![](./images/classbeming.gif)\n\n## Objectives\n\n1. Use CSS classes as an ontology of front-end project for clean communication between developers and non-tech staff\n2. Make CSS classes be an explicit and predictable informational layer\n3. Enforce declarative programming paradigm\n4. Enforce contract programming (via TypeScript)\n\n## Dev features\n\n1. Enforce \u003cu\u003esingle source of truth\u003c/u\u003e of class appending – treat as TypeScript-driven dedupe\n2. Require strict `boolean` for value of class condition\n3. Use IDE type hints as developers' UX for faster issues resolving\n4. BEM\n5. CSS-modules agnostic\n\nUse package like [`postcss-d-ts`](https://www.npmjs.com/package/postcss-d-ts) to prepare strict declaration of CSS \n\n## Installation and brief overview\n\n```bash\nnpm install --save react-classnaming\n```\n\n```typescript\nimport {\n  // Returns function for building `className: string` from conditioned CSS classes with \"context\" (if was provided) from `props` for using only declared CSS classes\n  classNaming, \n  \n  // Similar to classNaming, specifies mapping to component's (i.e. 3rd-party) `className`-related props\n  classNamesMap,\n  \n  // Identical function for TS restriction on classes determed in CSS and not used in component\n  classNamesCheck,\n  \n  // Works with BEM conditional object\n  classBeming\n} from \"react-classnaming\"\n\n// Default export is the most simple function\nimport classNaming from \"react-classnaming\"\n\nimport type {\n  // Type to declare component's self CSS classes\n  ClassNamesProperty, \n    \n  // Type to gather required CSS classes of sub-components\n  ClassNames, \n    \n  // `= string | undefined` – type to declare CSS class, global or local\n  ClassHash, \n    \n  // `= {className: string}` – useful shortcut\n  ClassNamed \n} from \"react-classnaming\"\n```\n\n## Basic usage\n\nExample of simple CSS classes conditioning – [./\\__tests__/readme.spec.tsx:9](./__tests__/readme.spec.tsx#L9-L31)\n\n```tsx\nimport classNaming from \"react-classnaming\"\n\ntype Props = {\n  isValid: boolean\n  readOnly: boolean\n}\n\n// isValid = false, readOnly = false\nfunction FormButtons({isValid, readOnly}: Props) {\n  const cssClasses = classNaming()\n  const buttonClass = cssClasses({\"button\": true}) // \"button\"\n\n  return \u003c\u003e\n    \u003cbutton {\n      ...buttonClass // className=\"button\" \n    }\u003eClose\u003c/button\u003e\n    \u003cbutton type=\"reset\" {\n      ...buttonClass({\"button--disabled\": readOnly}) // className=\"button\"\n    }\u003eReset\u003c/button\u003e \n                     { /* className=\"button_submit button button--disabled\" */ }\n    \u003cbutton type=\"submit\" className={`button_submit ${\n      buttonClass({\"button--disabled\": readOnly || !isValid}) // \"button button--disabled\"\n    }`}\u003eSubmit\u003c/button\u003e \n  \u003c/\u003e\n}  \n```\n\nAs shown, producing function `classNaming` returns a multipurpose object. It can be\n\n- \u003cu\u003erecalled\u003c/u\u003e to stack more CSS classes on conditions: `anotherClass = someClass({...})({...})`\n- \u003cu\u003edestructed in\u003c/u\u003e component's \u003cu\u003eprops\u003c/u\u003e as `className` singleton:  `\u003cdiv {...someClass}/\u003e\u003cbutton {...anotherClass}/\u003e` \n- used as a \u003cu\u003estring\u003c/u\u003e:  ` ``${someClass} ${anotherClass}`` `\n\n## Demos\n\nYou can find demonstration with all main points in folder [./\\__examples__/](./__examples__/), in addition *`*.test.*`* and *`*.spec.*`*. [\u003cimg src=\"./images/vscode.png\" width=\"50%\" align=\"right/\u003e](./images/vscode.png) \n\n## Getting more\n\n### Condition is strictly `boolean`\n\nConditions with falsy values may lead to hardly caught bugs due to not obvious behavior for humans. In addition, as a possible `true` shortcut, the value can be not empty string as `class-hash` from CSS-module, and \u003cu\u003e`undefined`\u003c/u\u003e for global CSS-class or modules simulation. Thus, to not keep in mind that `undefined` appears to be a truthy condition, it is prohibited on TypeScript level to mix in value type `boolean` with `ClassHash = string | undefined` and not allowed to use any other types like 0, null. [./\\__tests__/readme.spec.tsx:43](./__tests__/readme.spec.tsx#L43-L49)\n\n![](./images/classnaming_strict_condition.gif)\n\n### Single source of truth\n\nThere can be only ONE condition for each class in call pipe. Already conditioned classes are propagated to next call type notation so you can see currently stacked with according *modality*: `true`, `false` or `boolean`. [./\\__tests__/readme.spec.tsx:55](./__tests__/readme.spec.tsx#L55-L63)\n\n![classnaming_single_truth](./images/classnaming_single_truth.gif)\n\n### Declare own component's CSS classes\n\nOnly declared CSS classes will be allowed as keys with IDE hint on possibilities – [./\\__tests__/readme.spec.tsx:71](./__tests__/readme.spec.tsx#L71-L102)\n\n```diff\n+ import type { ClassHash, ClassNamesProperty } from \"react-classnaming\"\n\n+ type MyClassNames = ClassNamesProperty\u003c{\n+   button: ClassHash\n+   button_submit: ClassHash\n+   \"button--disabled\": ClassHash\n+ }\u003e\n\n- const cssClasses = classNaming()\n+ const cssClasses = classNaming\u003cMyClassNames\u003e()\n```\n\n![classnaming_declared](./images/classnaming_declared.gif)\n\n### BEM\n\nIt is possible to use BEM as condition query. With explicitly declared CSS classes (i.e. via [`postcss-plugin-d-ts`](https://www.npmjs.com/package/postcss-plugin-d-ts))  TS and IDE will check and hint on available blocks, elements, modifiers and values. [./\\__tests__/readme.spec.tsx:165](./__tests__/readme.spec.tsx#L165-L176)\n\n```diff\nimport {\n- classNaming \n+ classBeming\n} from \"react-classnaming\"\n\n- const cssClasses = classNaming\u003cMyClassNames\u003e()\n+ const bemClasses = classBeming\u003cMyClassNames\u003e()\n```\n\n![](./images/classbeming.gif)\n\n## Reference\n\n### type `ClassNamed`\nShortcut  for `{className: string}`. \n\n### type `ClassHash`\nFor serving global and local CSS classes and not moduled CSS stylesheets. CSS-module will be imported as `{[cssClasses: string]: string}`, while for ordinary CSS import `require` returns just empty object `{}`. Their common notation is `{[cssClasses: string]: string | undefined} `, thus `type ClassHash = string | undefined`\n\n### function [`classNaming`](https://github.com/askirmas/react-classnaming/projects/1)\n\nSets *context* for further type checks in supplying and toggling.\n\n```typescript\nclassNaming()\nclassNaming\u003cMyProps\u003e()\nclassNaming\u003cMyClassNames\u003e()\nclassNaming({classnames: require(\"./some.css\")})\nclassNaming({classnames: module_css, className})\nclassNaming(this.props)\n```\nReturns pipe-able (recallable) callback, that also can be destructed as `ClassNamed` or stringifyed\n\n```tsx\nconst cssClasses = classNaming(...)\nconst btnClass = cssClasses({ button })\n\nreturn                               \n  \u003cdiv {...btnClass } /\u003e\n  \u003cdiv data-block={`${btnClass}`} /\u003e\n  \u003cComponent {...{\n    ...btnClass(...)(...)(...)}\n  }/\u003e\n```\n\nOn TS-level checks that Component's propagated `className` and certain CSS-class are conditioned once\n\n```typescript\nconst conditionForClass1: boolean = false\nconst containerClass = classes(true, {class1: conditionForClass1})\n\nconst withClass1Twice = containerClass({\n  class2: true,\n  //@ts-expect-error – TS tracks that in chain there's only 1 place for class to be conditionally included \n  class1: otherCondiition\n})\n\nconst withClassNameTwice = containerClass(\n  //@ts-expect-error - Same for `className` - it is already added\n  true\n)\n```\n\nOn `const` hovering will be tooltip with already conditioned classes under this chain\n\n### function `classBeming`\n\nSets context to returned function for using BEM conditioned CSS classes queries. General argument's shape is\n\n```typescript\n// .src/bem.types.ts#L84-L90\ntype BemInGeneral = {\n  [base: string]: undefined | boolean | string\n  | (false|string)[]\n  | {\n    [mod: string]: undefined | boolean | string\n  }\n}\n```\n\nOutput logic: [./src/bem.core.test.ts:13](https://github.com/askirmas/react-classnaming/blob/main/src/bem.core.test.ts#L13-L35)\n\nFeatured example: [\\./\\__tests__/readme.spec.tsx:191](./__tests__/readme.spec.tsx#L191-L221)\n\n---\n\n### Setting options\n\nDefault options BEM naming:\n\n- Modifier's and value's separator is a double hyphen `\"--\"`\n- Element's separator is a double underscore `\"__\"`\n\nIt is required to change this options twice, both on JS and TS levels. \n\n- TS: in declaration file like [\\./\\__recipes\\__/global.d.ts](https://github.com/askirmas/react-classnaming/blob/main/__recipes__/global.d.ts) you to add those lines:\n\n```typescript\n/// \u003creference types=\"react-classnaming\" /\u003e\ndeclare namespace ReactClassNaming {\n  interface BemOptions {\n    elementDelimiter: \"_\";\n    modDelimiter: \"-\";\n  }\n}\n```\n\nAnd optionally in add to *tsconfig.json*:\n\n```diff\n  \"compilerOptions\": {\n    \"types\": [\n+     \"react-classnaming\"\n    ]\n  }\n```\n\n\n\n- JS: [./\\__recipes\\__/index.test.ts#L2-L7](https://github.com/askirmas/react-classnaming/blob/main/__recipes__/index.test.ts#L2-L7)\n\n  ```typescript\n  import setOptions from \"react-classnaming\"\n  setOptions({...})\n  ```\n\n  \n\n### function [`classNamesMap`](https://github.com/askirmas/react-classnaming/projects/5)\n\nFunction to map `classnames` to string props of some (i.e. 3rd-party) component.\n\n```tsx\nconst { Root } = classnames\nconst mapping = classNamesMap(classnames)\n\n\u003cThirdPartyComponent {...mapping({} as typeof ThirdPartyComponent, {\n  ContainerClassName: { Root, \"Theme--dark\": true },\n  Checked___true: classes({ \"Item--active\": true }),\n  Checked___false: {}\n})} /\u003e\n```\n\nFor hint will be used such props of target component that can be assigned to `string`. After calling `mapping` function and setting other properties, usual TypeScript will check for presence of target's required properties and other ordinary for TS things.\n\n![](./images/classnames_map.gif)\n\n### type [`ClassNamesProperty`](https://github.com/askirmas/react-classnaming/projects/3)\n\nDeclaration of self Component's `classnames`\n\n```typescript\n  type MyClasses = ClassNamesProperty\u003c{\n    class1: ClassHash\n    class2: ClassHash\n  }\u003e\n```\nCan be restricted to use classes only from CSS module. *Note* Currently no IDE's tooltip for hints\n\n```typescript\n  type MyProps = ClassNamesProperty\u003c\n    typeof some_module_css,\n    //@ts-expect-error\n    {class1: ClassHash, class2: ClassHash, unknownClass: ClassHash}\n  \u003e\n```\n\n### type [`ClassNames`](https://github.com/askirmas/react-classnaming/projects/2)\n\nCollects/gathers required `classnames` from used sub-Components\n\n```typescript\ntype MyProps = ClassNames\u003ctrue\u003e // === ClassNamed === {className: string}\ntype MyProps = ClassNames\u003cProps\u003e // {classnames: Props[\"classnames\"]}\ntype MyProps = ClassNames\u003ctypeof Component\u003e\ntype MyProps = ClassNames\u003ctrue, Props, typeof ClassComponent, typeof FunctionalComponent\u003e\n```\n\n```tsx\ntype Props = ClassNames\u003ctrue, Sub1Props, typeof Sub2\u003e\n  \nfunction Component({className, classnames, \"classnames\": {Sub1Class}}: Props) {\n  const classes = classNaming({classnames, className})\n  \n  return \u003cdiv\u003e\n    \u003cSub1 {...classes(true, {Sub1Class})} classnames={classnames}/\u003e\n    \u003cSub2 {...{\n        ...classes({Sub2Class: true}),\n\t\tclassnames\n    }}/\u003e\n  \u003c/div\u003e\n}\n```\n\n### type `ClassNamesFrom`\n\nObtain `classnames`-object from `props` of functional component, class component or props type\n\n```typescript\nClassNamesFrom\u003cComponentProps\u003e;\nClassNamesFrom\u003ctypeof Component\u003e;\n```\n\n### function [`classNamesCheck`](https://github.com/askirmas/react-classnaming/projects/4)\n\nIdentical function or returning constant `EMPTY_OBJECT` for keys check of not used classes in components tree \n\n```tsx\nimport css from \"./page.scss\"\nimport App from \"./App.tsx\"\n\nReactDOM.render(\u003cApp classnames={classNamesCheck(...)} /\u003e\n```\n- Dummies shape\n```tsx\n\u003cComponent classnames={classNamesCheck()} /\u003e;\n```\n- Checks CSS with defined (not indexed) classes keys. To produce such declaration you can use package [`postcss-plugin-d-ts`](https://www.npmjs.com/package/postcss-plugin-d-ts).\n```tsx\nimport type { ClassNamesFrom } from \"react-classnaming/types\";\nimport css_module from \"./some.css\"; // With class `.never-used {...}`\n\n\u003cComponent classnames={classNamesCheck(\n  css_module, \n  //@ts-expect-error Property 'never-used' is missing\n  {} as ClassNamesFrom\u003ctypeof Component\u003e\n)} /\u003e;\n```\n\n## Misc \n\n### Restructuring\n\n#### Using CSS-modules or simulation\n\nIt is possible to use CSS modules or simulation without \"context\" by supplying class-hash value with variable [./\\__tests__/readme.spec.tsx:114](./__tests__/readme.spec.tsx#L114-L153)\n\n```diff\n// CSS-module, assuming \"button\" will be replaced with \"BTN\"\n+ import css_module from \"./button.module.css\"\n+ const { button } = css_module\n// Module simulation\n+ type CssModuleSimulation = { button_submit: ClassHash }\n+ const { button_submit } = {} as CssModuleSimulation\n  \n  type MyClassNames = ClassNamesProperty\u003c\n+   typeof css_module \u0026\n+   CssModuleSimulation \u0026 \n    {\n-     button: ClassHash\n-     button_submit: ClassHash\n      \"button--disabled\": ClassHash\n    }\n \u003e\n\n- const buttonClass = cssClasses({ button: true })\n+ const buttonClass = cssClasses({ button })\n\n  \u003cbutton type=\"submit\" {...buttonClass({\n-    \"button_submit\": true, \n+    button_submit,\n    \"button--disabled\": readOnly || !isValid\n  })}\u003eSubmit\u003c/button\u003e  \n```\n\n### Versus [`classnames`](https://github.com/JedWatson/classnames#readme) package\n\nSee [src/versus-classnames.test.ts](./src/versus-classnames.test.ts)\n\n//TODO Copy here the most significant TS errors\n\n#### No css-modules, just simulation\n\n```tsx\nimport classnames from \"classnames\"\n\u003cdiv className={classnames(\"class1\", \"class2\")} /\u003e\n\u003cdiv id={classnames(\"class1\", \"class2\")} /\u003e\n\n// VERSUS\n\nimport css from \"./some.css\"\nimport classNaming, {classNamesCheck} from \"react-classnaming\"\nimport type {ClassNames} from \"react-classnaming\"\n\nconst { class1,\n  //@ts-expect-error\n  whatever\n} = classNamesCheck\u003c...\u003e(css)\n\nconst props: ClassNames\u003c\"class2\"\u003e = {\"classnames\": css}\n\nconst {class2} = props.classnames\n\n\u003cdiv {...classNaming({class1, class2})} /\u003e\n\u003cdiv id={`${classNaming({class1, class2})}`} /\u003e\n```\n\n#### CSS module\n\n```tsx\nimport module_css from \"./some.module.css\" // {\"class1\": \"hash1\", \"class2\": \"hash2\"}\n\nimport classnames_bind from \"classnames/bind\"\nconst cx = classnames_bind.bind(module_css)\n// No error on redundant CSS-class\n\u003cdiv className={cx(\"class1\", {\"class3\": true})} /\u003e\n\n// VERSUS\n\nimport classNaming from \"react-classnaming\"\nconst clases = classNaming({classnames: module_css})\n//@ts-expect-error Argument of type '\"class3\"' is not assignable to parameter\n\u003cdiv {...clases({class1: true, class3: true})} /\u003e\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faskirmas%2Freact-classnaming","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Faskirmas%2Freact-classnaming","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faskirmas%2Freact-classnaming/lists"}