{"id":1478,"date":"2024-03-15T14:33:09","date_gmt":"2024-03-15T17:33:09","guid":{"rendered":"https:\/\/benjaminray.com\/codebase\/?p=1478"},"modified":"2024-08-17T23:35:40","modified_gmt":"2024-08-18T02:35:40","slug":"styled-component-properties","status":"publish","type":"post","link":"https:\/\/benjaminray.com\/codebase\/styled-component-properties\/","title":{"rendered":"Styled Component Properties in React"},"content":{"rendered":"<p>By default, properties passed to a styled component are passed on as attributes to the native HTML element created. A regular property must be a valid HTML element attribute, or there will be an error in the console saying the property is not a valid HTML attribute. (Side note: It seems to accept all valid HTML attributes even if they're not valid for the specific HTML element. E.g., it will accept the &quot;size&quot; attribute for a div, even though that's not a valid DIV attribute.)<\/p>\n<p>To pass custom properties to the styled component that are consumed by the component instead of being passed on to the HTML element, use <a href=\"https:\/\/styled-components.com\/docs\/api#transient-props\" rel=\"noopener\" target=\"_blank\">Transient Properties<\/a>. Transient Properties are prefixed with $ and are accessed within the styled component through the props object.<\/p>\n<p>In the example below, the title is passed directly through to the div, and the other 3 properties are consumed by the styled div via the &quot;props&quot; object, e.g.: <code>props =&gt; props.$sampleFontSize<\/code>. The $size property (type BootstrapSize) is here to demonstrate the ability to reference one of multiple CSS objects, each containing various styles, stored in a Record object. The typical Bootstrap size is received as a prop and retrieves the Record containing the CSS object with the matching key.<\/p>\n<blockquote>\n<p>Note: The example below is a bit much for a single styled component. Usually you would layer the styled components with each one adding additional functionality, such as a styled div called SizedDiv that manages size, then one that called BackColorDiv that contains SizedDiv and adds a background color. Something like that.<\/p>\n<\/blockquote>\n<p>The styled div:<\/p>\n<pre><code class=\"language-jsx\">const SizeWrapper = styled.div&lt;{ title: string, $size: BootstrapSize, $isInlineEditorInBsModal: boolean, $sampleFontSize: number }&gt;`\n    font-size: ${props =&gt; (props.$sampleFontSize)}px;\n    ${props =&gt; (props.$isInlineEditorInBsModal ? &quot;position: relative;&quot; : &quot;&quot;)}\n    .mce-content-body {\n        ${props =&gt; (BootstrapStyles[props.$size])};\n    }\n    &amp; .custom-toolbar-wrapper {\n        position: absolute;\n    }\n`;\n<\/code><\/pre>\n<p>The Bootstrap Record:<\/p>\n<pre><code class=\"language-jsx\">const BootstrapStyles: Record&lt;BootstrapSize, CSSObject&gt; = {\n    sm: {\n        fontSize: &quot;0.875rem&quot;,\n        padding: &quot;0.25rem 0.5rem&quot;,\n        minHeight: &quot;calc(1.5em + 0.5rem + 2px)&quot;,\n        borderRadius: &quot;0.25rem&quot;,\n    },\n    md: {\n        fontSize: &quot;1rem&quot;,\n        padding: &quot;0.375rem 0.75rem&quot;,\n        minHeight: &quot;unset&quot; \/* No value for this, so use unset to get inherited\/initial value *\/,\n        borderRadius: &quot;0.375rem&quot;,\n    },\n    lg: {\n        fontSize: &quot;1.25rem&quot;,\n        padding: &quot;0.5rem 1rem&quot;,\n        minHeight: &quot;calc(1.5em + 1rem + 2px)&quot;,\n        borderRadius: &quot;0.5rem&quot;,\n    },\n};\n<\/code><\/pre>\n<p>And to actually use the styled div:<\/p>\n<pre><code class=\"language-jsx\">&lt;SizeWrapper \n  title={&quot;my custom title&quot;} \n  $size={props.size ?? &quot;sm&quot;} \n  $isInlineEditorInBsModal={props.isInlineEditorInBsModal ?? false} \n  $sampleFontSize={50}\n&gt;\n  {\/* amazing div content here *\/}\n&lt;\/SizeWrapper&gt;\n<\/code><\/pre>\n","protected":false},"excerpt":{"rendered":"<p>By default, properties passed to a styled component are passed on as attributes to the native HTML element created. A regular property must be a valid HTML element attribute, or  [&#8230;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2}},"categories":[28],"tags":[35,30,34],"class_list":["post-1478","post","type-post","status-publish","format-standard","hentry","category-react","tag-properties","tag-react","tag-styled-component"],"acf":[],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"jetpack_shortlink":"https:\/\/wp.me\/p9GNjN-nQ","jetpack_likes_enabled":false,"_links":{"self":[{"href":"https:\/\/benjaminray.com\/codebase\/wp-json\/wp\/v2\/posts\/1478","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/benjaminray.com\/codebase\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/benjaminray.com\/codebase\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/benjaminray.com\/codebase\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/benjaminray.com\/codebase\/wp-json\/wp\/v2\/comments?post=1478"}],"version-history":[{"count":9,"href":"https:\/\/benjaminray.com\/codebase\/wp-json\/wp\/v2\/posts\/1478\/revisions"}],"predecessor-version":[{"id":2533,"href":"https:\/\/benjaminray.com\/codebase\/wp-json\/wp\/v2\/posts\/1478\/revisions\/2533"}],"wp:attachment":[{"href":"https:\/\/benjaminray.com\/codebase\/wp-json\/wp\/v2\/media?parent=1478"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/benjaminray.com\/codebase\/wp-json\/wp\/v2\/categories?post=1478"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/benjaminray.com\/codebase\/wp-json\/wp\/v2\/tags?post=1478"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}